首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在iPhone 6/6+中,UIBezierPath未在UIViews的正确边框上绘制

在iPhone 6/6+中,UIBezierPath未在UIViews的正确边框上绘制
EN

Stack Overflow用户
提问于 2015-10-27 02:11:32
回答 2查看 771关注 0票数 2

我有一个用了很长时间的类,它在UIView (或从UIView继承的任何东西)周围绘制一个边框,并为该视图提供圆角。我今天做了一些测试(在升级到Xcode7并第一次在iOS 8.3上编译之后),注意到当我在模拟器上的iPhone 6/6+上运行时,UIView的右边缘被截断了(我没有实际的设备,但我假设结果是一样的)。

这里有一个简单的例子。注意我是如何给superview加上红色背景的,这样就可以跳出来了。子视图是具有固定高度并垂直对齐于视图中心的UIView。这是可行的。前缘和后缘应该固定在superview的边缘,正如您在此图中的约束中所看到的。注意内部的UILabelUIButton是如何像它们应该的那样居中的,但是UIView容器在右边被截断了,即使边框正在绘制。

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

最后,这是代码。在UIViewController中,我要求这样的边框。如果我注释掉这段代码,视图看起来还不错,当然只是我没有我想要的边框。

代码语言:javascript
运行
复制
BorderMaker *borderMaker = [[BorderMaker alloc] init];
[borderMaker makeBorderWithFourRoundCorners:_doneUpdatingView borderColor:[SharedVisualElements primaryFontColor] radius:8.0f];

和BorderMaker类:

代码语言:javascript
运行
复制
@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+屏幕宽度的事实。因为我没办法了,所以只是猜测而已。任何帮助都是非常感谢的。谢谢!

EN

回答 2

Stack Overflow用户

发布于 2015-10-27 03:08:04

BorderMaker根据输入视图的当前大小创建各种层和视图。当输入视图改变大小时,如何调整这些层和视图的大小?答案是:他们不需要。

您可以通过添加代码来以各种方式更新大小,但我不推荐这样做。由于您无论如何都要对所有四个角进行圆角处理,因此只需使用现有的CALayer支持来绘制边框、对角点进行圆角处理并屏蔽其内容,就可以更好地解决此问题。

下面是一个简单的BorderView类:

BorderView.h

代码语言:javascript
运行
复制
#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;

@end

BorderView.m

代码语言:javascript
运行
复制
#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上设置约束,它们将保持所有内容的大小和位置:

票数 2
EN

Stack Overflow用户

发布于 2015-10-27 11:34:33

我解决了这个问题。问题是我是从UIViewControllerviewDidLoad方法中调用这些BorderMaker方法的。我所要做的就是把它移到viewDidAppear上。据推测,正如Rob Mayoff所建议的那样,在将视图传递给BorderMaker类时,自动布局还没有完成,所以它得到的帧没有考虑屏幕的大小,而只是使用了IB中定义的宽度。

经过一些试验和错误,似乎viewDidAppear是我可以使用的最早的生命周期方法,用于自动布局的工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33352737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档