StackView实现自定义segment效果,且完美做到屏幕适配

需求如下描述:切换若干个选项,加载不同的页面。因为想做到可插拔的,所以考虑使用纯代码实现。

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颜色
  1. 因此最终考虑外层添加uiview,并支持背景色设置,一部分区域实现stackview,一部分区域留作显示底部的高亮显示下划线。但是考虑的可能存在如下的问题:
  2. 无法正确的到子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];

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值