您的位置:首页 > 移动开发 > IOS开发

IOS开发之自定义segment实现视图切换

2016-02-02 11:22 489 查看
近期在做项目的时候,需求需要App中有一个可以控制视图切换的控件,其实原理就是ios中的segment控件,但是sdk中的控件过于官方化,项目需要按照自己的设计图来实现它。所以研究了一下自己写了一个类似segment的控件,在这里跟大家分享一下。ps:控件外观还需要需改,这里只是将我实现的原理跟大家分享一下。

先看效果图:





通过点击下面的控件来实现视图的切换,当前的按钮会更改外观,而其他的按钮则会恢复未点击的效果。

逻辑代码如下:

[objc] view
plain copy

//

// CustomSegmentView.h

// PanderStrategy

//

// Created by silicon on 14-9-2.

// Copyright (c) 2014年 silicon. All rights reserved.

//

#import <UIKit/UIKit.h>

#import "UIButton+Icon.h"

@protocol CustomDelegate <NSObject>

- (void)buttonClick:(NSInteger)sender;

- (void)topButtonClick:(NSString *)sender;

@end

@interface CustomSegmentView : UIView

@property (nonatomic, strong) UIColor *cusBkColor;

@property (nonatomic, strong) UIColor *cusSelColor;

@property (nonatomic, strong) NSMutableArray *segmentArray;

@property (nonatomic, strong) UIColor *cusTextColor;

@property (assign) float cusbWidth;

@property (nonatomic, strong) UIColor *cusbColor;

@property (strong, nonatomic) id<CustomDelegate>myDelagte;

- (id)initWithFrame:(CGRect)frame

segmentArray:(NSArray *)_array

background:(UIColor *)_bkColor

selectedColor:(UIColor *)_selColor

borderColor:(UIColor *)_bColor

borderWidth:(float)_bWidth

textFont:(UIFont *)_font

textColor:(UIColor *)_textColor

position:(NSString *)_position;

//- (id)initWithOtherFrame:(CGRect)frame

// segmentArray:(NSArray *)_array

// background:(UIColor *)_bkColor

// selectedColor:(UIColor *)_selColor

// borderColor:(UIColor *)_bColor

// borderWidth:(float)_bWidth

// textFont:(UIFont *)_font

// textColor:(UIColor *)_textColor

// position:(NSString *)_position;

@end

实现文件:

[objc] view
plain copy

//

// CustomSegmentView.m

// PanderStrategy

//

// Created by silicon on 14-9-2.

// Copyright (c) 2014年 silicon. All rights reserved.

//

#import "CustomSegmentView.h"

@implementation CustomSegmentView

@synthesize cusBkColor = _cusBkColor;

@synthesize cusSelColor = _cusSelColor;

@synthesize segmentArray = _segmentArray;

@synthesize cusTextColor = _cusTextColor;

- (id)initWithFrame:(CGRect)frame

segmentArray:(NSArray *)_array

background:(UIColor *)_bkColor

selectedColor:(UIColor *)_selColor

borderColor:(UIColor *)_bColor

borderWidth:(float)_bWidth

textFont:(UIFont *)_font

textColor:(UIColor *)_textColor

position:(NSString *)_position

{

self = [super initWithFrame:frame];

if (self) {

// Initialization code

[self setBackgroundColor:_bkColor];

self.cusBkColor = _bkColor;

self.cusSelColor = _selColor;

self.cusTextColor = _textColor;

self.cusbWidth = _bWidth;

self.cusbColor = _bColor;

self.segmentArray = [[NSMutableArray alloc] init];

float width = frame.size.width/_array.count;

for (int i = 0; i < [_array count]; i++) {

UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];

// [btn setImageWithTitle:[UIImage imageNamed:@"email"] withTitle:[_array objectAtIndex:i] position:@"right" font:_font forState:UIControlStateNormal];

//不需要图片与文字一起显示

[btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];

[btn setFont:_font];

[btn addTarget:self action:@selector(clickSegment:) forControlEvents:UIControlEventTouchUpInside];

[_segmentArray addObject:btn];

[self addSubview:btn];

}

self.layer.masksToBounds=YES;

}

return self;

}

//- (id)initWithOtherFrame:(CGRect)frame segmentArray:(NSArray *)_array background:(UIColor *)_bkColor selectedColor:(UIColor *)_selColor borderColor:(UIColor *)_bColor borderWidth:(float)_bWidth textFont:(UIFont *)_font textColor:(UIColor *)_textColor position:(NSString *)_position{

// self = [super initWithFrame:frame];

// if (self) {

// // Initialization code

// [self setBackgroundColor:_bkColor];

// self.cusBkColor = _bkColor;

// self.cusSelColor = _selColor;

// self.cusTextColor = _textColor;

// self.cusbWidth = _bWidth;

// self.cusbColor = _bColor;

//

// self.segmentArray = [[NSMutableArray alloc] init];

//

// float width = frame.size.width/_array.count;

// for (int i = 0; i < [_array count]; i++) {

// UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(width * i, 0, width, frame.size.height)];

// [btn setTitle:[_array objectAtIndex:i] forState:UIControlStateNormal];

// [btn setFont:_font];

// [btn addTarget:self action:@selector(clickOtherSegment:) forControlEvents:UIControlEventTouchUpInside];

//

// [_segmentArray addObject:btn];

// [self addSubview:btn];

// }

// self.layer.masksToBounds=YES;

// }

// return self;

//}

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect

{

// Drawing code

}

*/

- (void)clickSegment:(id)sender{

UIButton *btn = (UIButton *)sender;

NSUInteger index = [_segmentArray indexOfObject:btn];

[self.myDelagte buttonClick:index];

[self updateSegmentStates:index];

}

//- (void)clickOtherSegment:(id)sender{

// UIButton *btn = (UIButton *)sender;

// NSUInteger index = [_segmentArray indexOfObject:btn];

//

// [self.myDelagte topButtonClick:btn.titleLabel.text];

// [self updateSegmentStates:index];

//}

- (void)updateSegmentStates:(NSUInteger )index{

self.layer.borderWidth=self.cusbWidth;

self.layer.borderColor=self.cusbColor.CGColor;

for (int i = 0; i < [_segmentArray count]; i++) {

if(i == index){

UIButton *btn = [_segmentArray objectAtIndex:index];

[btn setBackgroundColor:_cusSelColor];

[btn setTitleColor:_cusTextColor forState:UIControlStateNormal];

}else{

UIButton *btn = [_segmentArray objectAtIndex:i];

[btn setBackgroundColor:_cusBkColor];

[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

}

}

}

@end<span style="color: rgb(255, 255, 255); font-family: Menlo; font-size: 13px;">egmentView</span>

接下来,我们就来分析一下代码:

CustomSegmentView继承自UIView,这样在它初始化完成以后,我们就可以直接得到一个UIview的类型,然后通过addSubView的方式将他加入到主视图中。

我将他的initWithFrame函数扩展了一下,使它可以传入我们自定义的参数来初始化视图。

- (id)initWithFrame:(CGRect)frame

segmentArray:(NSArray *)_array

background:(UIColor *)_bkColor

selectedColor:(UIColor *)_selColor

borderColor:(UIColor *)_bColor

borderWidth:(float)_bWidth

textFont:(UIFont *)_font

textColor:(UIColor *)_textColor

position:(NSString *)_position

segmentArray:存放需要显示的视图名称标题

background:背景色

selectedColor:选中状态颜色

borderColor:边框颜色

borderWidth:边框粗细

textFont:标题字体及大小

textColor:字体颜色

position:显示位置,这个参数的作用是当segment中需要显示文字加图标的形式的时候,来定义图标显示方位的参数

逻辑代码很简单直接看源码就能理解了。

- (void)clickSegment:(id)sender函数是按钮响应的函数,在该类中,我们使用了代理的方式,告知使用该控件的视图,用户是点击的哪一个视图。

- (void)updateSegmentStates:(NSUInteger )index:函数则是用于更新按钮状态的函数,当某一个按钮被几点之后,外观需要怎么更改,以及其他未被点击的按钮背景外观如何

显示。

@protocol CustomDelegate <NSObject>

- (void)buttonClick:(NSInteger)sender;

- (void)topButtonClick:(NSString *)sender;

@end

则是我定义的代理,ios代理模式怎么使用我这里就不加解释了,我之前的文章有讲过,用户可自行查看。

接下来,由于有时候要显示的时图片加标题形式的segment,类似微信的底端,如图所示:



因为我们添加的都是UIButton,如果要显示成带文字跟图片的那我目前能想到的就只有两种情况,一种就是做背景图片文件跟图标一起做上去,然后点击的时候换背景。

还有一种情况就是我们去扩展一下UIButton的类别,使之可以支持文字跟图片。既然做开发么,当然不能偷懒选择第一种方式了,除非万不得已哦。我自定义了一个

UIButton+Icon的类别,然后在里面添加了扩展函数,代码如下:

[objc] view
plain copy

#import <Foundation/Foundation.h>

@interface UIButton (CustomBtn)

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;

@end

[objc] view
plain copy

#import "UIButton+Icon.h"

@implementation UIButton (CustomBtn)

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType{

CGSize titleSize = [title sizeWithFont:[UIFont systemFontOfSize:11.0f]];

[self.imageView setContentMode:UIViewContentModeCenter];

if([_position isEqualToString:@"left"]){

[self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2, 10.0, 0.0, 0)];

}else if([_position isEqualToString:@"top"]){

[self setImageEdgeInsets:UIEdgeInsetsMake(5.0, 0.0, 20.0, -titleSize.width)];

}else if([_position isEqualToString:@"right"]){

[self setImageEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2, titleSize.width + 25, 0.0, 0.0)];

}

[self setImage:image forState:stateType];

[self.titleLabel setContentMode:UIViewContentModeCenter];

[self.titleLabel setBackgroundColor:[UIColor clearColor]];

[self.titleLabel setFont:_font];

if([_position isEqualToString:@"left"]){

[self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,

image.size.width,

0.0,

0.0)];

}else if([_position isEqualToString:@"top"]){

[self setTitleEdgeInsets:UIEdgeInsetsMake(30.0,

-image.size.width,

0.0,

0.0)];

}else if([_position isEqualToString:@"right"]){

[self setTitleEdgeInsets:UIEdgeInsetsMake((self.frame.size.height - 50)/2,

-40.0,

0.0,

0)];

}

[self setTitle:title forState:stateType];

}

@end

- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;函数就是用来

设置图片以及文字共存的方法,用户可以通过传递 “left”,"top","right"参数来设置图标的显示位置。使用方法很简单,在我们添加UIButton的时候,调用该方法来进一步初始化按钮的显示。添加该方法后的显示效果如下:







我这边图省事,就全都使用了一个图标,当然界面还需要做的更加精细一些,在日后我会慢慢完善。

本文就到这吧,有什么错误的地方请大家指出来,谢啦!!!


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: