好久没有更新博客了,最近活比较忙,可能有3个礼拜没有来更新博客了。近期在做项目的时候,需求需要App中有一个可以控制视图切换的控件,其实原理就是ios中的segment控件,但是sdk中的控件过于官方化,项目需要按照自己的设计图来实现它。所以研究了一下自己写了一个类似segment的控件,在这里跟大家分享一下。ps:控件外观还需要需改,这里只是将我实现的原理跟大家分享一下。
先看效果图:
通过点击下面的控件来实现视图的切换,当前的按钮会更改外观,而其他的按钮则会恢复未点击的效果。
逻辑代码如下:
//
// 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
实现文件:
//
// 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的类别,然后在里面添加了扩展函数,代码如下:
#import <Foundation/Foundation.h>
@interface UIButton (CustomBtn)
- (void)setImageWithTitle:(UIImage *)image withTitle:(NSString *)title position:(NSString *)_position font:(UIFont *)_font forState:(UIControlState)stateType;
@end
#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的时候,调用该方法来进一步初始化按钮的显示。添加该方法后的显示效果如下:
我这边图省事,就全都使用了一个图标,当然界面还需要做的更加精细一些,在日后我会慢慢完善。
本文就到这吧,有什么错误的地方请大家指出来,谢啦!!!