ios UIView 只设置侧边框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11236607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:00:11  来源:igfitidea点击:

UIView set only side borders

objective-cioscocoa-touchuiview

提问by Mason

Is there a way to set the sides of the border of a UIView to one color and leave the top and the bottom another?

有没有办法将 UIView 边框的两侧设置为一种颜色,而将顶部和底部保留另一种颜色?

回答by Noah Witherspoon

Nope—CALayer borders don't support that behavior. The easiest way to accomplish what you want is adding an n-point-wide opaque subview with your desired border color as its background color on each side of your view.

不——CALayer 边界不支持这种行为。完成您想要的最简单的方法是添加一个n点宽的不透明子视图,并在视图的每一侧添加您想要的边框颜色作为其背景颜色。

Example:

例子:

CGSize mainViewSize = theView.bounds.size;
CGFloat borderWidth = 2;
UIColor *borderColor = [UIColor redColor];
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, borderWidth, mainViewSize.height)];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(mainViewSize.width - borderWidth, 0, borderWidth, mainViewSize.height)];
leftView.opaque = YES;
rightView.opaque = YES;
leftView.backgroundColor = borderColor;
rightView.backgroundColor = borderColor;

// for bonus points, set the views' autoresizing mask so they'll stay with the edges:
leftView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin;
rightView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin;

[theView addSubview:leftView];
[theView addSubview:rightView];

[leftView release];
[rightView release];

Note that this won't quite match the behavior of CALayer borders—the left and right border views will always be inside the boundaries of their superview.

请注意,这与 CALayer 边框的行为不太匹配——左右边框视图将始终位于其父视图的边界内。

回答by daniel kilinskas

The answer with the views that works like borders are very nice, but remember that every view is a UI Object that cost lots of memory.

像边框一样工作的视图的答案非常好,但请记住,每个视图都是一个消耗大量内存的 UI 对象。

I whould use uivew's layer to paint a stroke with color on an already existing UIview.

我会使用 uivew 的图层在已经存在的 UIview 上绘制带有颜色的笔划。

-(CAShapeLayer*)drawLineFromPoint:(CGPoint)fromPoint toPoint:(CGPoint) toPoint withColor:(UIColor *)color andLineWidth:(CGFloat)lineWidth{

CAShapeLayer *lineShape = nil;
CGMutablePathRef linePath = nil;

linePath = CGPathCreateMutable();
lineShape = [CAShapeLayer layer];

lineShape.lineWidth = lineWidth;
lineShape.strokeColor = color.CGColor;

NSUInteger x = fromPoint.x;
NSUInteger y = fromPoint.y;

NSUInteger toX = toPoint.x;
NSUInteger toY = toPoint.y;

CGPathMoveToPoint(linePath, nil, x, y);
CGPathAddLineToPoint(linePath, nil, toX, toY);

lineShape.path = linePath;
CGPathRelease(linePath);
return lineShape;}

and add it to our view.

并将其添加到我们的视图中。

CAShapeLayer* borderLine=[self drawLineFromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0,_myView.frame.size.height) withColor:[UIColor lightGrayColor] andLineWidth:1.0f];

[_myView.layer addSublayer:borderLine];

So... We take a point and actually painting a line from top to the bottom of our view. The result is that there is a line that looks like a one pixel width border.

所以......我们取一个点,实际上从我们视图的顶部到底部画一条线。结果是有一条线看起来像一个像素宽度的边框。

回答by 0x6A75616E

Updated for Swift 3.0

为 Swift 3.0 更新

I wrote a Swift extension (for a UIButton) that simulates setting a border on any side of a UIView to a given color and width. It's similar to @Noah Witherspoon's approach, but self-contained and autolayout constraint based.

我编写了一个 Swift 扩展(用于 UIButton),它模拟将 UIView 任何一侧的边框设置为给定的颜色和宽度。它类似于@Noah Witherspoon 的方法,但基于自包含和自动布局约束。

 // Swift 3.0
extension UIView {

  enum Border {
    case left
    case right
    case top
    case bottom
  }

  func setBorder(border: UIView.Border, weight: CGFloat, color: UIColor ) {

    let lineView = UIView()
    addSubview(lineView)
    lineView.backgroundColor = color
    lineView.translatesAutoresizingMaskIntoConstraints = false

    switch border {

    case .left:
      lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
      lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true
      lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
      lineView.widthAnchor.constraint(equalToConstant: weight).isActive = true

    case .right:
      lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
      lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true
      lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
      lineView.widthAnchor.constraint(equalToConstant: weight).isActive = true

    case .top:
      lineView.topAnchor.constraint(equalTo: topAnchor).isActive = true
      lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
      lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
      lineView.heightAnchor.constraint(equalToConstant: weight).isActive = true

    case .bottom:
      lineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
      lineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
      lineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
      lineView.heightAnchor.constraint(equalToConstant: weight).isActive = true
    }
  }
}    

回答by trumpetlicks

This sounds like one of two answers:

这听起来像是两个答案之一:

If your view is a static size, then just put a UIView behind it that is 2 pixels wider and 2 pixels shorter than your front view.

如果您的视图是静态大小,那么只需在其后面放置一个比前视图宽 2 像素、短 2 像素的 UIView。

If it is non-static sized then you could do the same, resizing the backing view whenever your foreground view is resized, or implement a custom object that implements a UIView, and implement (override) your own drawRect routine.

如果它是非静态大小,那么您可以执行相同的操作,在调整前景视图大小时调整背景视图的大小,或者实现一个实现 UIView 的自定义对象,并实现(覆盖)您自己的 drawRect 例程。

回答by weienw

NAUIViewWithBordersdid the trick for me. See also the creator's SO post here. Worth checking out if you need this functionality for more than a couple views.

NAUIViewWithBorders帮我解决了这个问题。另请参阅此处创建者的SO 帖子。如果您需要此功能来查看多个视图,则值得一试。

回答by Debaprio B

public extension UIView {
// Border type and arbitrary tag values to identify UIView borders as subviews
public enum BorderType: Int {
    case left = 20000
    case right = 20001
    case top = 20002
    case bottom = 20003
}

public func addBorder(borderType: BorderType, width: CGFloat, color: UIColor) {
    // figure out frame and resizing based on border type
    var autoresizingMask: UIViewAutoresizing
    var layerFrame: CGRect
    switch borderType {
    case .left:
        layerFrame = CGRect(x: 0, y: 0, width: width, height: self.bounds.height)
        autoresizingMask = [ .flexibleHeight, .flexibleRightMargin ]
    case .right:
        layerFrame = CGRect(x: self.bounds.width - width, y: 0, width: width, height: self.bounds.height)
        autoresizingMask = [ .flexibleHeight, .flexibleLeftMargin ]
    case .top:
        layerFrame = CGRect(x: 0, y: 0, width: self.bounds.width, height: width)
        autoresizingMask = [ .flexibleWidth, .flexibleBottomMargin ]
    case .bottom:
        layerFrame = CGRect(x: 0, y: self.bounds.height - width, width: self.bounds.width, height: width)
        autoresizingMask = [ .flexibleWidth, .flexibleTopMargin ]
    }

    // look for the existing border in subviews
    var newView: UIView?
    for eachSubview in self.subviews {
        if eachSubview.tag == borderType.rawValue {
            newView = eachSubview
            break
        }
    }

    // set properties on existing view, or create a new one
    if newView == nil {
        newView = UIView(frame: layerFrame)
        newView?.tag = borderType.rawValue
        self.addSubview(newView!)
    } else {
        newView?.frame = layerFrame
    }
    newView?.backgroundColor = color
    newView?.autoresizingMask = autoresizingMask
}