這個(gè)是對(duì)上篇文章的優(yōu)化丧叽。
上篇下劃線的效果直接是消失和出現(xiàn)骚灸,這篇文章里面改成下劃線的移動(dòng)效果翁巍,不會(huì)顯得突兀驴一。
最重要的注意點(diǎn):
(1)不要把下劃線添加到button里面,要不然怎么著都是出現(xiàn)消失的效果灶壶。(千萬記赘味稀)
(2)可以通過調(diào)節(jié)動(dòng)畫的時(shí)間看效果。
初始化的代碼沒有用到,沒有刪除胸懈,不影響担扑。
只改動(dòng)了XXTitleView.m的代碼,直接上代碼了:
//
// XXHomeView.m
// XXTableBar
//
// Created by shine on 2016/12/26.
// Copyright ? 2016年 shine. All rights reserved.
//
#import "XXTitleView.h"
//#import "UIView+Extension.h"
@interface XXTitleView ()
//保存所有的button
@property (strong, nonatomic) NSMutableArray *titleButtons;
//titleView
@property (weak, nonatomic) UIScrollView *titleView;
//記錄上一個(gè)按鈕的寬度
@property(nonatomic, assign)CGFloat lastbtnW;
//記錄當(dāng)前選中的按鈕
@property (weak, nonatomic) UIButton *currentButton;
//記錄當(dāng)前選中按鈕的下劃線
@property (strong, nonatomic) UIView *currentLine;
@end
@implementation XXTitleView
#pragma mark -- 懶加載
- (NSMutableArray *)titleButtons{
if(_titleButtons == nil){
_titleButtons = [NSMutableArray array];
}
return _titleButtons;
}
- (UIView *)currentLine{
if (_currentLine == nil) {
_currentLine = [[UIView alloc] init];
_currentLine.backgroundColor = [UIColor redColor];
}
return _currentLine;
}
#pragma mark -- set方法
- (void)setTitleArray:(NSArray *)titleArray{
if(_titleArray == nil){
_titleArray = titleArray;
}
[self setupTitleView];
}
#pragma mark -- 初始化
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
//初始化界面
}
return self;
}
- (void)setupTitleView{
//NSLog(@"我是setupTitleView");
//1.創(chuàng)建titileView
UIScrollView *titleView = [[UIScrollView alloc] init];
titleView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
titleView.showsVerticalScrollIndicator = NO;
titleView.showsHorizontalScrollIndicator = NO;
titleView.bounces = NO;
titleView.backgroundColor = [UIColor lightGrayColor];
[self addSubview:titleView];
self.titleView = titleView;
//2.創(chuàng)建8-10個(gè)按鈕趣钱,并將其加入到titleView
float btnMargin = 5;
float btnX = 0;
for (int i = 0; i < self.titleArray.count; i++) {
//2.1 根據(jù)文字計(jì)算button的寬度
NSDictionary *arributes = @{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]};
NSStringDrawingOptions option = NSStringDrawingUsesFontLeading | NSStringDrawingUsesDeviceMetrics | NSStringDrawingUsesLineFragmentOrigin;
CGSize titleSize = [self.titleArray[i] boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:option attributes:arributes context:nil].size;
CGFloat textW = titleSize.width + 2 * btnMargin;
self.lastbtnW = textW;
btnX = btnX + textW;
//NSLog(@"btnX = %f",btnX);
//2.2 創(chuàng)建button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = i;
//button.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
button.frame = CGRectMake(btnX - self.lastbtnW, 0, textW, self.frame.size.height);
//2.3 設(shè)置button的文字,不要使用button.titleLabel.text,不要使用sizetofit
[button setTitle:self.titleArray[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
//[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
button.titleLabel.font = [UIFont boldSystemFontOfSize:14];
//2.4 添加button到視圖中
[self.titleButtons addObject:button];
[self.titleView addSubview:button];
//2.5添加button點(diǎn)擊事件
[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
//3.設(shè)置titleView的contentSize
self.titleView.contentSize = CGSizeMake(CGRectGetMaxX(button.frame), 0);
//4.程序運(yùn)行時(shí)默認(rèn)在第一個(gè)按鈕
if(i == 0){
UIButton *firstBtn = self.titleButtons[i];
self.currentButton = firstBtn;
self.currentButton.selected = YES;
//創(chuàng)建一根下劃線涌献,添加到titleView中(千萬不能放在button里面,要不然沒有移動(dòng)的效果首有,而是突然消失和出現(xiàn)的效果)
//線寬和選中的button一樣寬燕垃,線高為3
self.currentLine.frame = CGRectMake(0, self.currentButton.frame.size.height - 3, self.currentButton.frame.size.width, 3);
[self.titleView addSubview:self.currentLine];
}
}
}
- (void)clickButton:(UIButton *)button{
NSLog(@"%d",button.tag);
//將之前選中的按鈕的selected設(shè)置為no
//獲取之前選中按鈕的寬度,為計(jì)算伸縮比例作準(zhǔn)備
CGFloat lastButtonW = self.currentButton.frame.size.width;
self.currentButton.selected = NO;
//將現(xiàn)在選中的按鈕的selected設(shè)置為yes井联,并將此按鈕賦值給當(dāng)前按鈕卜壕。
button.selected = YES;
self.currentButton = button;
[UIView animateWithDuration:0.1 animations:^{
CGFloat lineW = self.currentButton.frame.size.width;
//CGFloat lineH = 3;
//獲取當(dāng)前按鈕的center并將其賦給下劃線(有問題,從上往下掉為什么)
CGPoint buttonCenter = self.currentButton.center;
CGPoint lineCenter = self.currentLine.center;
lineCenter.x = buttonCenter.x;
self.currentLine.center = lineCenter;
//計(jì)算伸縮的比例
CGFloat sx = lineW / lastButtonW;
self.currentLine.transform = CGAffineTransformScale(self.currentLine.transform, sx, 1);
}];
//獲取當(dāng)前按鈕的x值,只有當(dāng)?shù)谌N情況下才需要改變scrollview的偏移
//1.獲取到當(dāng)前點(diǎn)擊按鈕的x值,加上此按鈕的寬度與中心作比較低矮,如果小于寬度的中心印叁,將titleVIew的偏移量設(shè)置為0
//2.獲取到當(dāng)前點(diǎn)擊按鈕的x值,減去此按鈕的寬度與中心作比較军掂,如果大于寬度的中心轮蜕,將titleVIew的x偏移量設(shè)置為contenSize-屏幕的寬度
//3.其他情況。按鈕相對(duì)于屏幕的位移+此按鈕的一半寬度與屏幕中心作對(duì)比蝗锥。
//獲取當(dāng)前按鈕的x值
CGFloat buttonX = CGRectGetMaxX(self.currentButton.frame) - self.currentButton.frame.size.width;
//獲取當(dāng)前scrollView的x偏移量
CGFloat offsetX = self.titleView.contentOffset.x;
//取得當(dāng)前按鈕此時(shí)相對(duì)于屏幕的值
CGFloat widthToScreen = buttonX - offsetX;
//獲取屏幕寬度的一半
CGFloat halfWidth = [[UIScreen mainScreen] bounds].size.width * 0.5;
//當(dāng)前按鈕的x值加上按鈕的一半寬度
CGFloat buttonXaddHalfWidth = widthToScreen + 0.5 * self.currentButton.frame.size.width;
if ((buttonX + 0.5 * self.currentButton.frame.size.width) < halfWidth) {
//button的x值+button一半的寬度小于屏幕寬度的一半
//將titleVIew的偏移量設(shè)置為0
[self.titleView setContentOffset:CGPointMake(0, 0) animated:YES];
}
else if ((self.titleView.contentSize.width - buttonX - 0.5 * self.currentButton.frame.size.width < halfWidth)){
//button的x值-button一半的寬度大于屏幕寬度的一半
//將titleVIew的x偏移量設(shè)置為contenSize-屏幕的寬度
CGFloat titleViewOffsetX = self.titleView.contentSize.width - 2 * halfWidth;
[self.titleView setContentOffset:CGPointMake(titleViewOffsetX, 0) animated:YES];
}
else{
//相對(duì)于屏幕的寬度+按鈕寬度的一半<屏幕的中心跃洛, 則向右移一點(diǎn)(即titleVIew的x偏移量減小)
//相對(duì)于屏幕的寬度+按鈕寬度的一半>屏幕的中心终议, 則向左移一點(diǎn)(即titleVIew的x偏移量增大)
//改變偏移量
CGFloat titleViewOffsetX = self.titleView.contentOffset.x - (halfWidth - buttonXaddHalfWidth);
[self.titleView setContentOffset:CGPointMake(titleViewOffsetX, 0) animated:YES];
}
}
@end