UIButton 顶部和底部边框附加线

UIButton Top and Bottom Border additional line

我正在尝试向 uibutton 添加顶部和底部边框我添加边框的函数如下所示

    CALayer *topBorder = [CALayer layer];

    topBorder.frame = CGRectMake(os, 1.0f, b.bounds.size.width - (os * 2.0f), 1.0f);

    topBorder.backgroundColor = [c1 CGColor];

    [b.layer addSublayer:topBorder];

    CALayer *bottomBorder = [CALayer layer];

    bottomBorder.frame = CGRectMake(os, b.bounds.size.height, b.bounds.size.width - (os * 2.0f), 1.0f);

    bottomBorder.backgroundColor = [c1 CGColor];

    [b.layer addSublayer:bottomBorder];

    //os..offset, b..uibutton, c1..color

当我在 viewDidAppear 中调用该函数时,这工作正常(但会有延迟)但是当我将它放在 viewdidlayoutsubviews 中时,它会添加一个额外的行,不知何故看起来像这样

我为其超级视图设置了前导和尾随 space,我在这里做错了什么?

当您的视图出现在屏幕上并且每次从导航流中的其他视图控制器返回时,都会执行 viewDidAppear。所以你的代码多次添加行。您可以查看视图控制器生命周期 here.

如果你想删除"delay"并执行一次,把你的代码写在viewDidLoad.

更新

我看到两种方法。创建一个 UIButton 子类然后:

  1. 如果你想继续使用 CALayers,你需要在你的按钮改变它的大小时调用重绘方法。如果改变动画会出现怪异的神器。

  2. 不错。我建议您使用 'drawRect' 绘制此线并使用按钮框架动态计算线 XY。如果你改变按钮的大小,无论动画与否......没问题,Core Animation 可以完成所有工作。

    - (void)drawRect:(CGRect)rect
    {
        // Frames
        CGRect frame = self.bounds;
    
        // Parameters (change these values if you want to change appearance)
        UIColor *lineColor = [UIColor colorWithRed: 0.5 green: 0.5 blue: 0.5 alpha: 1];
        CGFloat topRatioPositionY = 0.02;
        CGFloat middleRatioPositionY = 0.6;
        CGFloat bottomRatioPositionY = 0.98;
        CGFloat middleRatioPositionX = 0.33333;
        CGFloat lineWidth = 1.0;
    
        //// Top line
        UIBezierPath* bezierPath = [UIBezierPath bezierPath];
        [bezierPath moveToPoint: CGPointMake(CGRectGetMinX(frame), CGRectGetMinY(frame) + topRatioPositionY * CGRectGetHeight(frame))];
        [bezierPath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 1.00000 * CGRectGetWidth(frame), CGRectGetMinY(frame) + topRatioPositionY * CGRectGetHeight(frame))];
        [lineColor setStroke];
        bezierPath.lineWidth = lineWidth;
        [bezierPath stroke];
    
    
        // Middle line
        UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
        [bezier2Path moveToPoint: CGPointMake(CGRectGetMinX(frame), CGRectGetMinY(frame) + bottomRatioPositionY * CGRectGetHeight(frame))];
        [bezier2Path addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 1.00000 * CGRectGetWidth(frame), CGRectGetMinY(frame) + bottomRatioPositionY * CGRectGetHeight(frame))];
        [lineColor setStroke];
        bezier2Path.lineWidth = lineWidth;
        [bezier2Path stroke];
    
    
        // Bottom Line
        UIBezierPath* bezier3Path = [UIBezierPath bezierPath];
        [bezier3Path moveToPoint: CGPointMake(CGRectGetMinX(frame), CGRectGetMinY(frame) + middleRatioPositionY * CGRectGetHeight(frame))];
        [bezier3Path addLineToPoint: CGPointMake(CGRectGetMinX(frame) + middleRatioPositionX * CGRectGetWidth(frame), CGRectGetMinY(frame) + middleRatioPositionY * CGRectGetHeight(frame))];
        [lineColor setStroke];
        bezier3Path.lineWidth = lineWidth;
        [bezier3Path stroke];
    
    }// drawRect:
    

我已将此 source code 附加到带有 CALayer 和 UIBezierPath 解决方案的行中。触摸按钮,看看它们变化时的区别。