iOS_28仿QQ空间_控制器的切换_自定义segmentCtrol

iOS_28仿QQ空间_控制器的切换_自定义segmentCtrol,第1张

概述最终效果图: 主控制器 //// BeyondViewController.m// 28_QQ空间//// Created by beyond on 14-9-1.// Copyright (c) 2014年 com.beyond. All rights reserved.// 主控制器包括两个部分:左边的Dock,右边的contentView,其中左边Dock又包括三个部分

最终效果图:




主控制器



////  BeyondVIEwController.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  主控制器包括两个部分:左边的Dock,右边的contentVIEw,其中左边Dock又包括三个部分(顶部的头像按钮、中部的选项卡、底部的一个整体),其中底部的整体 包含三个按钮「说说、拍照、日记」,中部的选项卡包含六个自定义item「全部动态、与我相关、照片墙、电子相框、好友、更多」#import "BeyondVIEwController.h"// 控制器#import "BeyondNavigationController.h"#import "NanaController.h"// Dock#import "Dock.h"#import "DockMIDdleTabbar.h"#import "DockBottomVIEw.h"#import "DocktopIconBtn.h"// 协议#import "DockMIDdleTabbarDelegate.h"#import "DockBottomVIEwDelegate.h"@interface BeyondVIEwController () <DockMIDdleTabbarDelegate,DockBottomVIEwDelegate>@property (nonatomic,weak) Dock *dock;// 存放右边子控制器的vIEw@property (nonatomic,weak) UIVIEw *contentVIEw;@end@implementation BeyondVIEwController#pragma mark - 生命周期方法- (voID)vIEwDIDLoad{    [super vIEwDIDLoad];    // 0.设置控制器背景色 为全局深灰色    self.vIEw.backgroundcolor = kGlobalBgcolor;        // 1.初始化Dock    [self setupDock];        // 2.初始化contentVIEw    [self setupContentVIEw];        // 3.初始化所有子控制器    [self setupChildVIEwControllers];        // 4.默认点击头像    [self iconBtnClicked];}#pragma mark - 左边Dock// 1.初始化Dock- (voID)setupDock{    // 1.添加dock    Dock *dock = [Dock alLocinit];    // 重要~~~高度自动伸缩     dock.autoresizingMask = UIVIEwautoresizingFlexibleHeight;    dock.height = self.vIEw.height;    [self.vIEw addSubvIEw:dock];    self.dock = dock;        // 2.根据当前的屏幕方向设置dock的属性    [self.dock rotate:UIInterfaceOrIEntationIsLandscape(self.interfaceOrIEntation)];        // 3.设置tabbar的代理    self.dock.tabbar.delegate = self;        // 4.监听头像的点击    [self.dock.iconBtn addTarget:self action:@selector(iconBtnClicked) forControlEvents:UIControlEventtouchUpInsIDe];        // 5.设置bottomVIEw的代理,监听bottomVIEw内部的三个按钮点击    self.dock.bottomVIEw.delegate = self;}// 4.点击头像- (voID)iconBtnClicked{    // 子控制器的个数 共 7个 0~5对应Tabbar,索引为6才是头像对应的控制器    int count = self.childVIEwControllers.count;        // 遍历,获得当前正在显示的控制器的索引    int from = 0;    for (int i = 0; i<count; i++) {        UIVIEwController *vc = self.childVIEwControllers[i];                if (vc.vIEw.supervIEw) {            // 如果有控制器正在显示            from = i;            break;        }    }        // 最后一个子控制器的索引,即头像对应的控制器    int iconVCIndex = count - 1;        // 调用自定义方法(实为代理方法),从当前正在显示的控制器切换到头像控制器    [self tabbar:nil dIDSelectbuttonFrom:from to:iconVCIndex];        // 重要~~~让tabbar里面的当前选中的按钮 取消选中    [self.dock.tabbar deselectCurrentItem];}#pragma mark - 右边ContentVIEw// 2.初始化contentVIEw- (voID)setupContentVIEw{    // 1.创建ContentVIEw    UIVIEw *contentVIEw = [UIVIEw alLocinit];    // dock宽    CGfloat dockW = self.dock.wIDth;    // x    contentVIEw.x = dockW;    // 屏幕宽    CGfloat screenW = UIInterfaceOrIEntationIsLandscape(self.interfaceOrIEntation) ?1024:768;    // 宽    contentVIEw.wIDth = screenW - dockW;    // 高    contentVIEw.height = self.vIEw.height;    contentVIEw.autoresizingMask = UIVIEwautoresizingFlexibleHeight;    [self.vIEw addSubvIEw:contentVIEw];    self.contentVIEw = contentVIEw;        // 2.UIVIEw的分类方法 添加 pan 手势 (为d簧效果作准备)    [self.contentVIEw addPanGestureWithTarget:self action:@selector(dragContentVIEw:)];}// d簧效果  触发了pan手势就会调用(开始-->ing-->end)- (voID)dragContentVIEw:(UIPanGestureRecognizer *)pan{    //  分类方法,d簧效果,仅是可拖动的d簧效果,没有进行边界检测    [pan addFlexableEffect];    }#pragma mark - 所有子控制器// 3.初始化所有子控制器- (voID)setupChildVIEwControllers{    // tabbar对应的6个子控制器    // 0~5 对应Tabbar上6个item    UIVIEwController *vc0 = [UIVIEwController alLocinit];    vc0.Title = @"全部动态";    [self setupOneChildVIEwController:vc0];        UIVIEwController *vc1 = [UIVIEwController alLocinit];    vc1.Title = @"与我相关";    [self setupOneChildVIEwController:vc1];        UIVIEwController *vc2 = [UIVIEwController alLocinit];    vc2.Title = @"照片墙";    [self setupOneChildVIEwController:vc2];        UIVIEwController *vc3 = [UIVIEwController alLocinit];    vc3.Title = @"电子相框";    [self setupOneChildVIEwController:vc3];        UIVIEwController *vc4 = [UIVIEwController alLocinit];    vc4.Title = @"好友";    [self setupOneChildVIEwController:vc4];        UIVIEwController *vc5 = [UIVIEwController alLocinit];    vc5.Title = @"更多";    [self setupOneChildVIEwController:vc5];        //  7.点击主控制器左边Dock 最上方的头像,来到nana控制器    NanaController *nana =[NanaController alLocinit];    [self setupOneChildVIEwController:nana];}// 3.1.自定义方法,用导航控制器,包装一个子控制器 (也可以重写父类的addChildVIEwController方法)- (voID)setupOneChildVIEwController:(UIVIEwController *)vc{    // 不要自动扩张至全屏    vc.edgesForExtendedLayout = UIRectEdgeNone;    BeyondNavigationController *nav = [[BeyondNavigationController alloc] initWithRootVIEwController:vc];    [self addChildVIEwController:nav];}#pragma mark - 父类方法-屏幕即将旋转//  当屏幕即将旋转的时候调用//  toInterfaceOrIEntation 旋转完毕后的最终方向//  duration               旋转动画所花费的时间- (voID)willRotatetoInterfaceOrIEntation:(UIInterfaceOrIEntation)toInterfaceOrIEntation duration:(NSTimeInterval)duration{            // 1.设置Dock        //控制器监测到了 屏幕旋转的事件,通知内部子控件Dock        [self.dock rotate:UIInterfaceOrIEntationIsLandscape(toInterfaceOrIEntation)];                // 2.设置contentVIEw        // dock宽        CGfloat dockW = self.dock.wIDth;        // x        self.contentVIEw.x = dockW;        // 屏幕宽 (因为是willRotate,所以要反着来)        CGfloat screenW = UIInterfaceOrIEntationIsLandscape(self.interfaceOrIEntation) ?768:1024;        // 宽        self.contentVIEw.wIDth = screenW - dockW;            }#pragma mark - Tabbar的代理方法- (voID)tabbar:(DockMIDdleTabbar *)tabbar dIDSelectbuttonFrom:(int)from to:(int)to{    // 1.新控制器(实为导航控制器)    BeyondNavigationController *newNaviVC = self.childVIEwControllers[to];    // 防止重复点击    if (newNaviVC.vIEw.supervIEw) return;    // 2.设置新控制器的frame填充整个contentVIEw    newNaviVC.vIEw.frame = self.contentVIEw.bounds;        // 3.取出导航控制器的根控制器设置背景色    UIVIEwController *newRootVC = [newNaviVC.childVIEwControllers firstObject];    newRootVC.vIEw.backgroundcolor = kcolor(212,212,212);        // 4.旧控制器    BeyondNavigationController *oldNaviVC;    // 取出最后一个子控制器 (即头像按钮控制器)    BeyondNavigationController *lastNaviVC = [self.childVIEwControllers lastObject];    if (lastNaviVC.vIEw.supervIEw) {        // 特例,如果是最后一个添加的头像控制器在显示 (头像按钮控制器正在显示,则旧控制器就是头像控制器)        oldNaviVC = lastNaviVC;    } else {        // 如果是 0 ~ 5这几个Tabbar里面的控制器,则可以直接 统一切换        oldNaviVC = self.childVIEwControllers[from];    }        // 5.转场动画   调用UIVIEw的分类方法,实现三维转场动画    [self.contentVIEw switcholdVIEw:oldNaviVC.vIEw toNewVIEw:newNaviVC.vIEw];    }#pragma mark - bottomVIEw代理方法- (voID)bottomMenu:(DockBottomVIEw *)bottomVIEw dIDClickbutton:(BottomVIEwBtnType)btnType{    switch (btnType) {        case BottomVIEwBtnTypeBlog: // 日志        case BottomVIEwBtnTypeMood: // 心情        case BottomVIEwBtnTypePhoto: // 照片        {            NanaController *nanaVC = [NanaController alLocinit];            BeyondNavigationController *nav = [[BeyondNavigationController alloc] initWithRootVIEwController:nanaVC];            // 设置modal 的类型:            nav.modalPresentationStyle = UIModalPresentationFormSheet;            [self presentVIEwController:nav animated:YES completion:nil];            break;        }                    default:            break;    }}@end



VIEw的封装




Dock

////  Dock.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  主控制器左边的Dock,其包括三个部分(顶部的头像按钮、中部的选项卡、底部的一个整体),其中底部的整体 包含三个按钮「说说、拍照、日记」,中部的选项卡包含六个自定义item「全部动态、与我相关、照片墙、电子相框、好友、更多」#import <UIKit/UIKit.h>@class  DocktopIconBtn,DockMIDdleTabbar,DockBottomVIEw;@interface Dock : UIVIEw// 当外界收到屏幕旋转的消息时,会调用该方法 告之我,我会拦截此方法,调整好自己在相应的屏幕下的frame,接着我再把此消息传达给我自己内部的子控件们,让其调整frame- (voID)rotate:(BOol)lanscape;#pragma mark - 全部提供给控制器访问,设置代理等@property (weak,nonatomic,Readonly) DocktopIconBtn *iconBtn;@property (weak,Readonly) DockMIDdleTabbar *tabbar;@property (weak,Readonly) DockBottomVIEw *bottomVIEw;@end

////  Dock.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  主控制器左边的Dock,其包括三个部分(顶部的头像按钮、中部的选项卡、底部的一个整体),其中底部的整体 包含三个按钮「说说、拍照、日记」,中部的选项卡包含六个自定义item「全部动态、与我相关、照片墙、电子相框、好友、更多」#import "Dock.h"#import "DocktopIconBtn.h"#import "DockMIDdleTabbar.h"#import "DockBottomVIEw.h"@implementation Dock#pragma mark - 生命周期方法- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 1.添加子控件 头像        [self setupiconBtn];                // 2.添加子控件 选项卡        [self setupTabbar];                // 3.添加子控件 底部整体        [self setupBottomVIEw];    }    return self;}// 1.添加子控件 头像- (voID)setupiconBtn{    DocktopIconBtn *iconBtn = [[DocktopIconBtn alloc] init];    [self addSubvIEw:iconBtn];    _iconBtn = iconBtn;}// 2.添加子控件 选项卡- (voID)setupTabbar{    DockMIDdleTabbar *tabbar = [[DockMIDdleTabbar alloc] init];    // 粘着底部    tabbar.autoresizingMask = UIVIEwautoresizingFlexibletopmargin;    [self addSubvIEw:tabbar];    _tabbar = tabbar;}// 3.添加子控件 底部整体- (voID)setupBottomVIEw{    DockBottomVIEw *bottomVIEw = [[DockBottomVIEw alloc] init];    // 粘着底部    bottomVIEw.autoresizingMask = UIVIEwautoresizingFlexibletopmargin;    [self addSubvIEw:bottomVIEw];    _bottomVIEw = bottomVIEw;}#pragma mark - 拦截外部屏幕变化时的传递过来的消息// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape{    // 1.转达消息,首先 调整底部菜单,才能设置其他的子控件    [self.bottomVIEw rotate:lanscape];        // 2.然后才 设置dock自己的宽度 跟随 底部的宽度    self.wIDth = self.bottomVIEw.wIDth;        // 3.转达消息,然后才调整 tabbar    [self.tabbar rotate:lanscape];    self.tabbar.y = self.bottomVIEw.y - self.tabbar.height;        // 4.转达消息,最后才调整 头像    [self.iconBtn rotate:lanscape];}@end

Dock的底部三个按钮作为一个整体

////  DockBottomVIEw.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  左侧dock 的底部的一个整体,包含 三个按钮,分别是 说说、拍照、日记#import <UIKit/UIKit.h>@protocol DockBottomVIEwDelegate;@interface DockBottomVIEw : UIVIEw// 定义枚举,分别代表底部整体里面的三个按钮,它们是 说说、拍照、日记typedef enum {    BottomVIEwBtnTypeMood,// 心情    BottomVIEwBtnTypePhoto,// 照片    BottomVIEwBtnTypeBlog // 日志} BottomVIEwBtnType;// 代理,告诉代理点击的按钮类型@property (nonatomic,weak) ID<DockBottomVIEwDelegate> delegate;// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape;@end

////  DockBottomVIEw.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//#import "DockBottomVIEw.h"// 通知代理,点击的按钮类型#import "DockBottomVIEwDelegate.h"@implementation DockBottomVIEw#pragma mark - 生命周期- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 初始化3个按钮,并且绑定tag为定义好的枚举类型(通知代理时用)        [self setupbuttonWithIcon:@"tabbar_mood" tag:BottomVIEwBtnTypeMood];        [self setupbuttonWithIcon:@"tabbar_photo" tag:BottomVIEwBtnTypePhoto];        [self setupbuttonWithIcon:@"tabbar_blog" tag:BottomVIEwBtnTypeBlog];    }    return self;}// 自定义方法,创建一个按钮,参数:图片名,绑定的tag为按钮枚举类型(通知代理时用)- (voID)setupbuttonWithIcon:(Nsstring *)icon tag:(BottomVIEwBtnType)tag{    UIbutton *button = [[UIbutton alloc] init];    // 绑定的tag为按钮枚举类型(通知代理时用)    button.tag = tag;    // 图标按原始大小,文字无    // 选中时的背景图片  拉伸    // 监听点击事件,好通知代理,并且传递按钮的tag过去    [button setBtnIcon:icon Title:nil selectedBgimg:@"tabbar_separate_selected_bg" target:self action:@selector(buttonClick:) event:UIControlEventtouchUpInsIDe];        [self addSubvIEw:button];}#pragma mark - 监听点击- (voID)buttonClick:(UIbutton *)button{    if ([self.delegate respondsToSelector:@selector(bottomMenu:dIDClickbutton:)]) {        [self.delegate bottomMenu:self dIDClickbutton:button.tag];    }}#pragma mark - 拦截外部屏幕变化时的传递过来的消息// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape{    // 三个按钮    int count = self.subvIEws.count;    if (lanscape) {        // 横屏时,横着排,宽度大一些        self.wIDth = kBottomBtnLanscapeW * count;        self.height = kBottomBtnH;        // 一一设置frame,横着排        for (int i = 0; i<count; i++) {            UIbutton *button = self.subvIEws[i];            button.x = i * kBottomBtnLanscapeW;            button.y = 0;            button.wIDth = kBottomBtnLanscapeW;            button.height = kBottomBtnH;        }    } else {        // 竖屏,立着排,宽度窄一些        self.wIDth = kBottomBtnPortraitW;        self.height = kBottomBtnH * count;        // 一一设置frame,立着排        for (int i = 0; i<count; i++) {            UIbutton *button = self.subvIEws[i];            button.x = 0;            button.y = i * kBottomBtnH;            button.wIDth = kBottomBtnPortraitW;            button.height = kBottomBtnH;        }    }    // 底部整体 自己的y值:Dock的高度 - 自己的高度    self.y = self.supervIEw.height - self.height;}@end
Dock底部整体  代理协议
////  DockBottomVIEwDelegate.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  左侧dock 的底部的一个整体,分别是 说说、拍照、日记//  定义协议,目的是通知外界:底部的一个整体中某一个按钮被点击了#import <Foundation/Foundation.h>@class DockBottomVIEw;@protocol DockBottomVIEwDelegate <NSObject>@optional- (voID)bottomMenu:(DockBottomVIEw *)bottomVIEw dIDClickbutton:(BottomVIEwBtnType)btnType;@end


Dock中部的Tabbar

////  DockMIDdleTabbar.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  左侧dock 的中部的 Tabbar,选项卡,共有 6个,//  它们分别是:「全部动态」「与我相关」「照片墙」「电子相框」「好友」「更多」#import <UIKit/UIKit.h>@protocol DockMIDdleTabbarDelegate;@interface DockMIDdleTabbar : UIVIEw// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape;@property (nonatomic,weak) ID<DockMIDdleTabbarDelegate> delegate;// 供控制器调用,取消选中 当前选中的Btn- (voID)deselectCurrentItem;@end


////  DockMIDdleTabbar.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//#import "DockMIDdleTabbar.h"// 监听点击,通知代理#import "DockMIDdleTabbarDelegate.h"#import "DockMIDdleTabbarItem.h"// BeyondVIEwController成为DockMIDdleTabbar的代理// BeyondVIEwController监听DockMIDdleTabbar内部按钮的点击事件@interface DockMIDdleTabbar()// 选中的那个item@property (weak,nonatomic) DockMIDdleTabbarItem *selectedbutton;@end@implementation DockMIDdleTabbar#pragma mark - 生命周期- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 一次性,初始化6个按钮        [self setupbuttonWithIcon:@"tab_bar_Feed_icon" Title:@"全部动态"];        [self setupbuttonWithIcon:@"tab_bar_passive_Feed_icon" Title:@"与我相关"];        [self setupbuttonWithIcon:@"tab_bar_pic_wall_icon" Title:@"照片墙"];        [self setupbuttonWithIcon:@"tab_bar_e_album_icon" Title:@"电子相框"];        [self setupbuttonWithIcon:@"tab_bar_frIEnd_icon" Title:@"好友"];        [self setupbuttonWithIcon:@"tab_bar_e_more_icon" Title:@"更多"];    }    return self;}// 自定义方法,添加一个item- (voID)setupbuttonWithIcon:(Nsstring *)icon Title:(Nsstring *)Title{    DockMIDdleTabbarItem *button = [[DockMIDdleTabbarItem alloc] init];    // 绑定tag 0~5    button.tag = self.subvIEws.count;    // 设置标题    // 监听点击    // 图标按原始大小    // 选中时的背景图片  拉伸    [button setBtnIcon:icon Title:Title selectedBgimg:@"tabbar_separate_selected_bg" target:self action:@selector(buttonClick:) event:UIControlEventtouchDown];        [self addSubvIEw:button];}#pragma mark - 监听点击,通知代理- (voID)buttonClick:(DockMIDdleTabbarItem *)button{    // 1.通知代理    if ([self.delegate respondsToSelector:@selector(tabbar:dIDSelectbuttonFrom:to:)]) {        [self.delegate tabbar:self dIDSelectbuttonFrom:self.selectedbutton.tag to:button.tag];    }        // 2.标准三步曲,切换按钮状态    [button switchSelectedStatusWitholdBtn:self.selectedbutton];}#pragma mark - 拦截外部屏幕变化时的传递过来的消息// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape{    // 根据子控件个数,设置不同屏幕下的frame    int count = self.subvIEws.count;    // 选项卡的 宽 始终为dock的宽    self.wIDth = self.supervIEw.wIDth;    // 选项卡的 高 和 子item的个数有关    self.height = kBottomBtnH * count;    // 遍历子控件,一一设置frame,立着排列    for (int i = 0; i<count; i++) {        DockMIDdleTabbarItem *button = self.subvIEws[i];        button.wIDth = self.wIDth;        button.height = kBottomBtnH;        button.x = 0;        button.y = i * button.height;    }}#pragma mark - 仅供外界(控制器)调用- (voID)deselectCurrentItem{    self.selectedbutton.selected = NO;}@end

Dock中部Tabbar的代理要实现的协议

////  DockMIDdleTabbarDelegate.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  DockMIDdleTabbar定义好的协议,到时候监听到点击时,通知代理#import <Foundation/Foundation.h>@class DockMIDdleTabbar;@protocol DockMIDdleTabbarDelegate <NSObject>@optional- (voID)tabbar:(DockMIDdleTabbar *)tabbar dIDSelectbuttonFrom:(int)from to:(int)to;@end

Dock中部的选项卡里面的一个按钮


////  DockMIDdleTabbarItem.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  Dock中部的选项卡里面的一个按钮#import "DockMIDdleTabbarItem.h"// 横屏时,图片所占的宽度比#define kImageLanscpaeWIDthRatio 0.4@implementation DockMIDdleTabbarItem#pragma mark - 生命周期- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 图片的伸缩 模式        self.imageVIEw.contentMode = UIVIEwContentModeCenter;        // 标题的字体        self.TitleLabel.Font = [UIFont systemFontOfSize:20];    }    return self;}#pragma mark - 父类方法// 不需要高亮状态,只要选中即可- (voID)setHighlighted:(BOol)highlighted {}//  调整 图片的frame- (CGRect)imageRectForContentRect:(CGRect)contentRect{    if (self.wIDth > kBottomBtnLanscapeW) {        // 横屏时,左图,右文字        CGfloat imageW = self.wIDth * kImageLanscpaeWIDthRatio;        CGfloat imageH = self.height;        return CGRectMake(0,imageW,imageH);    } else {        // 竖屏时,只有图片,没有文字        return self.bounds;    }}//  调整 标题的frame- (CGRect)TitleRectForContentRect:(CGRect)contentRect{    if (self.wIDth > kBottomBtnLanscapeW) {        // 横屏时,右文字        CGfloat TitleX = self.wIDth * kImageLanscpaeWIDthRatio;        CGfloat TitleW = self.wIDth - TitleX;        CGfloat TitleH = self.height;        return CGRectMake(TitleX,TitleW,TitleH);    } else {        // 竖屏时,没有文字        return CGRectZero;    }}@end

Dock顶部的头像按钮

////  DocktopIconBtn.h//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  左侧dock 的顶部的 头像按钮#import <UIKit/UIKit.h>@interface DocktopIconBtn : UIbutton// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape;@end

////  DocktopIconBtn.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  左侧dock 的顶部的 头像按钮#import "DocktopIconBtn.h"@implementation DocktopIconBtn#pragma mark - 生命周期方法- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        // 设置头像按钮 的图片        [self setimage:[UIImage image@R_567_4041@Withname:@"nanalogo.jpg"] forState:UIControlStatenormal];        // 设置头像按钮 的标题        [self setTitle:@"nana" forState:UIControlStatenormal];        // 设置头像按钮 的标题对齐方式        self.TitleLabel.textAlignment = NSTextAlignmentCenter;        // 给图层加圆角        self.imageVIEw.layer.cornerRadius = 10;    }    return self;}#pragma mark - 父类方法//  调整 图片的frame- (CGRect)imageRectForContentRect:(CGRect)contentRect{    if (self.wIDth > kBottomBtnPortraitW) {        // 横屏        // 图片宽为按钮宽,正方形        CGfloat imageW = self.wIDth;        CGfloat imageH = imageW;        return CGRectMake(0,图片占据整个按钮        return self.bounds;    }}//  调整 标题的frame- (CGRect)TitleRectForContentRect:(CGRect)contentRect{    if (self.wIDth > kBottomBtnPortraitW) {        // 横屏        // 标题在图片下方,占据按钮除图片以外的空间        CGfloat TitleY = self.wIDth;        CGfloat TitleW = self.wIDth;        CGfloat TitleH = self.height - TitleY;        return CGRectMake(0,TitleY,标题隐藏        return CGRectZero;    }}#pragma mark - 拦截外部屏幕变化时的传递过来的消息// 当外界收到屏幕旋转的消息时,让其调整frame- (voID)rotate:(BOol)lanscape{    if (lanscape) {        // 横屏        // 头像按钮的宽为 父控件Dock的宽度的三分之一        self.wIDth = self.supervIEw.wIDth * 0.35;        // 头像按钮的高为 宽+40,其中40是为标题预留的        self.height = self.wIDth + 40;        // 头像按钮居dock的顶部中心        self.y = 60;        self.x = (self.supervIEw.wIDth - self.wIDth) * 0.5;    } else {        // 竖屏时,仍占dock的顶部中心,但此时宽高一致,标题不再显示        self.y = 40;        self.x = 10;        self.wIDth = self.supervIEw.wIDth - 2 * self.x;        self.height = self.wIDth;    }}@end


自定义Segement控件及其使用


////  BeyondSegment.h//  28_QQ空间////  Created by beyond on 14-9-2.//  copyright (c) 2014年 com.beyond. All rights reserved.//  自定义控件 segmentControl,每一个按钮都是segmentbarBtn#import <UIKit/UIKit.h>@interface Segmentbar : UIVIEw// 字串 数组,根据数组长度 决定 生成多少个SegmentbarBtn,并为其Title赋值@property (nonatomic,strong) NSArray *TitlesArr;//  设置当前选中的segmentbarBtn@property (nonatomic,assign) int selectedSegmentIndex;@end

////  BeyondSegment.m//  28_QQ空间////  Created by beyond on 14-9-2.//  copyright (c) 2014年 com.beyond. All rights reserved.//  自定义控件 segmentControl,每一个按钮都是segmentbarBtn#import "Segmentbar.h"#import "SegmentbarBtn.h"@interface Segmentbar()@property (nonatomic,weak) SegmentbarBtn *selectedSegment;@end@implementation Segmentbar#pragma 拦截setter,添加内部子控件- (voID)setTitlesArr:(NSArray *)TitlesArr{    _TitlesArr = TitlesArr;        // 1.为健壮性,先移除以前创建的所有按钮    [self.subvIEws makeObjectsPerformSelector:@selector(removeFromSupervIEw)];        // 2.添加新的按钮    int count = TitlesArr.count;    for (int i = 0; i<count; i++) {        SegmentbarBtn *segment = [[SegmentbarBtn alloc] init];        // 设置tag        segment.tag = i;        // 设置文字        [segment setBtnTitlecolorFornormal:TitlesArr[i]];        // 设置背景        Nsstring *bgname = nil;        Nsstring *selectedBgname = nil;        if (i == 0) { // 最左边            bgname = @"SegmentedControl_left_normal";            selectedBgname = @"SegmentedControl_left_Selected";        } else if (i == count - 1) { // 最右边            bgname = @"SegmentedControl_Right_normal";            selectedBgname = @"SegmentedControl_Right_Selected";        } else { // 中间            bgname = @"SegmentedControl_normal";            selectedBgname = @"SegmentedControl_Selected";        }        // 设置正常和选中状态下的背景图片(已拉伸)        [segment setBtnBgimgFornormalAndSelecteDWithname:bgname selectedname:selectedBgname];        // 监听点击        [segment addTarget:self action:@selector(segmentClick:) forControlEvents:UIControlEventtouchDown];                [self addSubvIEw:segment];    }}// 监听点击- (voID)segmentClick:(SegmentbarBtn *)segment{    // 标准三步曲,切换选中按钮状态    [segment switchSelectedStatusWitholdBtn:self.selectedSegment];}// For循环遍历数据时,每添加一个按钮时,就重新调整一下,它们的宽,x- (voID)layoutSubvIEws{    [super layoutSubvIEws];        int count = self.subvIEws.count;    // 平铺,宽度均分    CGfloat buttonW = self.wIDth / count;    CGfloat buttonH = self.height;    // 取出每一个,设置x    for (int i = 0; i<count; i++) {        SegmentbarBtn *button = self.subvIEws[i];        button.wIDth = buttonW;        button.height = buttonH;        button.y = 0;        button.x = i * buttonW;    }}#pragma mark - 供外界调// 开放接口,供外界调用 setter- (voID)setSelectedSegmentIndex:(int)selectedSegmentIndex{    int count = self.TitlesArr.count;    // 健壮性检测    if (selectedSegmentIndex < 0 || selectedSegmentIndex >= count) return;        // 取出对应位置的按钮    SegmentbarBtn *segment = self.subvIEws[selectedSegmentIndex];        // 调用自定义方法,选中该索引下的按钮    [self segmentClick:segment];}// 开放接口,供外界调用 getter- (int)selectedSegmentIndex{    return self.selectedSegment.tag;}@end



在Nana控制器中使用自定义控件segment,

及用代码创建storyboard中描述的控制器

////  NanaController.m//  28_QQ空间////  Created by beyond on 14-9-1.//  copyright (c) 2014年 com.beyond. All rights reserved.//  点击主控制器左边Dock 最上方的头像,来到此控制器#import "NanaController.h"#import "Segmentbar.h"@interface NanaController ()//@property (nonatomic,weak) Segmentbar *sc;@end@implementation NanaController// 1.设置导航栏左边按钮- (voID)setupleftbarBtn{    self.Title = @"I'm nana";    // 分类方法    self.navigationItem.leftbarbuttonItem = [UIbarbuttonItem barbuttonItemwithTitle:@"退出系统" style:UIbarbuttonItemStyleDone target:self action:@selector(logout)];}#pragma mark - 生命周期- (voID)vIEwDIDLoad{    [super vIEwDIDLoad];    // 1.设置导航栏左边按钮    [self setupleftbarBtn];    // 2.设置导航栏的TitleVIEw为自定义的segment控件    [self setupSegmentbar];        }// 2.设置导航栏的TitleVIEw为自定义的segment控件- (voID)setupSegmentbar{    // 数据源模型决定 vIEw    NSArray *TitlesArr = @[@"全部",@"好友动态",@"我的关注"];    if (iOS7) {        // iOS7使用自定义的扁平化风格        UISegmentedControl *sc = [[UISegmentedControl alloc] initWithItems:TitlesArr];        sc.frame = CGRectMake(0,300,32);        sc.selectedSegmentIndex = 0;        // 使用tintcolor进行着色        sc.tintcolor = [UIcolor graycolor];        self.navigationItem.TitleVIEw = sc;    } else {        Segmentbar *sc = [[Segmentbar alloc] init];        sc.TitlesArr = TitlesArr;        sc.frame = CGRectMake(0,32);        sc.selectedSegmentIndex = 0;        self.navigationItem.TitleVIEw = sc;    }}// 点击退出登录,回到登录控制器,即创建Main.storyboard里面的初始控制器- (voID)logout{    // 调用控制器的分类方法从storyboard中创建指定ID的控制器    self.vIEw.window.rootVIEwController = [UIVIEwController alLocinitFromStoryboard:nil withID:@"LoginController" bundle:nil];}@end
总结

以上是内存溢出为你收集整理的iOS_28仿QQ空间_控制器的切换_自定义segmentCtrol全部内容,希望文章能够帮你解决iOS_28仿QQ空间_控制器的切换_自定义segmentCtrol所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1088672.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存