需求如下描述:切换若干个选项,加载不同的页面。因为想做到可插拔的,所以考虑使用纯代码实现。
1.首先考虑使用uiview,配套uibutton和uiview作为高亮时候视图的修饰部分用。但是发现在写约束的时候必须得到横竖屏对应的宽度才好对button进行平均分布。其中一种方式就是需要在外部检测屏幕旋转,然后重新布局frame。但是显然这种方式不太合适,外部做的处理较多。考虑放弃。
2. 于是了解到了一个实现的新view, stackview. 可以根据平行或者垂直的方向了平均分割各个子view。遇到一些点,mark一下
- uibutton - (void)setAttributedTitle:(nullable NSAttributedString *)title forState:(UIControlState) 可以自定义一些字符串显示的颜色,根据字符串的长度添加不同类型的下划线等操作,但是明显不足的问题是,这种方式的下划线和文字的间距不能手动修改,无法满足ui设计上的一些特殊的需求。最终放弃。
- stackview继承于uiview类,因此本身无法将uiview添加成子view,这样也就不好实现添加底部的修饰图
- stackview本身无法改变background颜色
- 因此最终考虑外层添加uiview,并支持背景色设置,一部分区域实现stackview,一部分区域留作显示底部的高亮显示下划线。但是考虑的可能存在如下的问题:
- 无法正确的到子uibutton的frame从而无法正确设置底部line的约束,但是经过尝试将stack view进行layoutifneeded的操作证明完全可以,log显示的各个button的frame完美兼容横竖屏。因此最终方案定下来了。
简单例子代码如下:
UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIColor redColor];
[self addSubview:backgroundView];
UIButton *button1 = [[UIButton alloc] init];
button1.selected = NO;
button1.backgroundColor = [UIColor redColor];
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@" 我是Button1 "]; //实现的例子,button的文字下方添加下划线效果
NSRange strRange = {0,[str length]};
[str addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:strRange];
[str addAttribute:NSUnderlineColorAttributeName value:[UIColor yellowColor] range:strRange];
[button1 setAttributedTitle:str forState:UIControlStateNormal];
UIButton *button2 = [[UIButton alloc] init];
NSMutableAttributedString *str2 = [[NSMutableAttributedString alloc] initWithString:@" 我是Button2 "];
NSRange strRange2 = {0,[str2 length]};
[str2 addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:strRange2];
[button2 setAttributedTitle:str2 forState:UIControlStateNormal];
UIButton *button3 = [[UIButton alloc] init];
NSMutableAttributedString *str3 = [[NSMutableAttributedString alloc] initWithString:@" 我是Button3 "];
NSRange strRange3 = {0,[str3 length]};
[str3 addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:strRange3];
[button3 setAttributedTitle:str3 forState:UIControlStateNormal];
self.segmentView = [[USMTSegmentView alloc] initWithArrangedSubviews:@[button1, button2, button3]];
self.segmentView.alignment = UIStackViewAlignmentCenter;
self.segmentView.axis = UILayoutConstraintAxisHorizontal;
self.segmentView.distribution = UIStackViewDistributionFillEqually;
[backgroundView addSubview:self.segmentView];
//segment view constraints
self.segmentView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *segmentViewTop = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeTop multiplier:1.0 constant: 0];
//NSLayoutConstraint *segmentViewCenter = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant: 0.0f];
NSLayoutConstraint *segmentViewHeight = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant: 80];
//NSLayoutConstraint *segmentViewWidth = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant: [self.segmentView.segmentViewStyleProperty.segmentsTitleArray count] * SEGMENT_ITEM_WIDTH];
//left and right
NSLayoutConstraint *segmentViewLeft = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeLeft multiplier:1.0 constant: 0.0f];
NSLayoutConstraint *segmentViewRight = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeRight multiplier:1.0 constant: 0.0f];
NSArray *segmentViewConstraints = [NSArray arrayWithObjects:segmentViewTop, segmentViewLeft, segmentViewHeight, segmentViewRight, nil];
[backgroundView addConstraints:segmentViewConstraints];
[self.segmentView layoutIfNeeded];
NSLog(@"--- the button frame is --- %f %f %f %f ", button1.frame.origin.x, button1.frame.origin.y, button1.frame.size.width, button1.frame.size.height);
NSLog(@"--- the button frame is --- %f %f %f %f ", button2.frame.origin.x, button2.frame.origin.y, button2.frame.size.width, button2.frame.size.height);
//line view
UIView *line1 = [[UIView alloc] init];
line1.backgroundColor = [UIColor blueColor];
[backgroundView addSubview:line1];
line1.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:line1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:button1 attribute:NSLayoutAttributeBottom multiplier:1.0 constant: 15];
//NSLayoutConstraint *segmentViewCenter = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant: 0.0f];
NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:line1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:button1 attribute:NSLayoutAttributeLeft multiplier:1.0 constant: 15];
//NSLayoutConstraint *segmentViewWidth = [NSLayoutConstraint constraintWithItem:self.segmentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant: [self.segmentView.segmentViewStyleProperty.segmentsTitleArray count] * SEGMENT_ITEM_WIDTH];
//left and right
NSLayoutConstraint *right = [NSLayoutConstraint constraintWithItem:line1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:button1 attribute:NSLayoutAttributeRight multiplier:1 constant: -15];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:line1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1.0 constant: 1.0f];
NSArray *constraints = [NSArray arrayWithObjects:top, left, right, height, nil];
[backgroundView addConstraints:constraints];