我有一个用了很长时间的类,它在UIView (或从UIView继承的任何东西)周围绘制一个边框,并为该视图提供圆角。我今天做了一些测试(在升级到Xcode7并第一次在iOS 8.3上编译之后),注意到当我在模拟器上的iPhone 6/6+上运行时,UIView的右边缘被截断了(我没有实际的设备,但我假设结果是一样的)。
这里有一个简单的例子。注意我是如何给superview加上红色背景的,这样就可以跳出来了。子视图是具有固定高度并垂直对齐于视图中心的UIView。这是可行的。前缘和后缘应该固定在superview的边缘,正如您在此图中的约束中所看到的。注意内部的UILabel和UIButton是如何像它们应该的那样居中的,但是UIView容器在右边被截断了,即使边框正在绘制。

以下是故事板设置。具有边框的UIView具有固定的高度,垂直居中,前后边缘固定在superview上:

最后,这是代码。在UIViewController中,我要求这样的边框。如果我注释掉这段代码,视图看起来还不错,当然只是我没有我想要的边框。
BorderMaker *borderMaker = [[BorderMaker alloc] init];
[borderMaker makeBorderWithFourRoundCorners:_doneUpdatingView borderColor:[SharedVisualElements primaryFontColor] radius:8.0f];和BorderMaker类:
@implementation BorderMaker
- (void) makeBorderWithFourRoundCorners : (UIView *) view
borderColor : (UIColor *) borderColor
radius : (CGFloat) radius
{
UIRectCorner corners = UIRectCornerAllCorners;
CGSize radii = CGSizeMake(radius, radius);
[self drawBorder : corners
borderColor : borderColor
view : view
radii : radii];
}
- (void) drawBorder : (UIRectCorner) corners
borderColor : (UIColor *) borderColor
view : (UIView *) view
radii : (CGSize) radii
{
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:view.bounds
byRoundingCorners:corners
cornerRadii:radii];
// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
view.layer.mask = cornerMaskLayer;
// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = borderColor.CGColor;
strokeLayer.lineWidth = 1.5; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.
// Transparent view that will contain the stroke layer
UIView *strokeView = [[UIView alloc] initWithFrame:view.bounds];
strokeView.userInteractionEnabled = NO; // in case your container view contains controls
[strokeView.layer addSublayer:strokeLayer];
// configure and add any subviews to the container view
// stroke view goes in last, above all the subviews
[view addSubview:strokeView];
}在该类中的某个地方,视图边界似乎没有反映出AutoLayout拉伸视图以填充更大的iPhone 6/6+屏幕宽度的事实。因为我没办法了,所以只是猜测而已。任何帮助都是非常感谢的。谢谢!
发布于 2015-10-27 03:08:04
BorderMaker根据输入视图的当前大小创建各种层和视图。当输入视图改变大小时,如何调整这些层和视图的大小?答案是:他们不需要。
您可以通过添加代码来以各种方式更新大小,但我不推荐这样做。由于您无论如何都要对所有四个角进行圆角处理,因此只需使用现有的CALayer支持来绘制边框、对角点进行圆角处理并屏蔽其内容,就可以更好地解决此问题。
下面是一个简单的BorderView类:
BorderView.h
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface BorderView : UIView
@property (nonatomic, strong) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;
@endBorderView.m
#import "BorderView.h"
@implementation BorderView
- (void)setBorderColor:(UIColor *)borderColor {
self.layer.borderColor = borderColor.CGColor;
}
- (UIColor *)borderColor {
CGColorRef cgColor = self.layer.borderColor;
return cgColor ? [UIColor colorWithCGColor:self.layer.borderColor] : nil;
}
- (void)setBorderWidth:(CGFloat)borderWidth {
self.layer.borderWidth = borderWidth;
}
- (CGFloat)borderWidth {
return self.layer.borderWidth;
}
- (void)setCornerRadius:(CGFloat)cornerRadius {
self.layer.cornerRadius = cornerRadius;
}
- (CGFloat)cornerRadius {
return self.layer.cornerRadius;
}
@end现在,如果您在故事板中创建了一个视图,并将其自定义类设置为BorderView,则可以在故事板中设置其边框:

请注意,我在故事板中设置了“剪贴子视图”,因此如果子视图恰好超出BorderView的四舍五入边界,它将剪切子视图。
如果您在BorderView上设置约束,它们将保持所有内容的大小和位置:

发布于 2015-10-27 11:34:33
我解决了这个问题。问题是我是从UIViewController的viewDidLoad方法中调用这些BorderMaker方法的。我所要做的就是把它移到viewDidAppear上。据推测,正如Rob Mayoff所建议的那样,在将视图传递给BorderMaker类时,自动布局还没有完成,所以它得到的帧没有考虑屏幕的大小,而只是使用了IB中定义的宽度。
经过一些试验和错误,似乎viewDidAppear是我可以使用的最早的生命周期方法,用于自动布局的工作。
https://stackoverflow.com/questions/33352737
复制相似问题