Swift - 带约束的圆形 UIImageView

Posted

技术标签:

【中文标题】Swift - 带约束的圆形 UIImageView【英文标题】:Swift - Rounded UIImageView with constraints 【发布时间】:2016-05-26 14:45:42 【问题描述】:

我有一个简单的视图控制器,我想在其中放置一个圆形图像视图。 (我根本不使用情节提要,我想以编程方式处理所有内容) 但是,无论我做什么,图像视图都是方形的。

class DetailViewController: UIViewController

    // MARK: - Controls
    var imageView:UIImageView!;
    var label:UILabel = UILabel();
    var button:UIButton = UIButton();
    var close:UIButton = UIButton();

    // MARK: - Fields
    var person: Person!;

    // MARK: - Constructors
    init(person: Person) 
        super.init(nibName: nil, bundle: nil);

        self.person = person;
        self.view.backgroundColor = UIColor.whiteColor();
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    override func viewDidLoad() 
        super.viewDidLoad();

        self.imageView = UIImageView();
        self.imageView.image = person.picture;
        self.imageView.translatesAutoresizingMaskIntoConstraints = false;
        self.imageView.contentMode = .ScaleAspectFill;
        self.view.addSubview(self.imageView);

        self.label.translatesAutoresizingMaskIntoConstraints = false;
        self.label.text = person.name;
        self.label.sizeToFit();
        self.view.addSubview(self.label);

        self.button.setTitle("Open Webview", forState: .Normal);
        self.button.setTitleColor(UIColor.whiteColor(), forState: .Normal);
        self.button.backgroundColor = UIColor.grayColor();
        self.button.translatesAutoresizingMaskIntoConstraints = false;
        self.button.addTarget(self, action: #selector(DetailViewController.open), forControlEvents: .TouchUpInside);
        self.view.addSubview(self.button);

        self.close.setTitle("Close", forState: .Normal);
        self.close.setTitleColor(UIColor.blueColor(), forState: .Normal);
        self.close.backgroundColor = UIColor.clearColor();
        self.close.translatesAutoresizingMaskIntoConstraints = false;
        self.close.addTarget(self, action: #selector(DetailViewController.closeView), forControlEvents: .TouchUpInside);
        self.view.addSubview(self.close);
        self.close.alpha = 0;
        if( UIDevice.currentDevice().userInterfaceIdiom == .Pad) 
            self.close.alpha = 1;
        

        // Center constraint
        self.view.addConstraint(NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0));
        self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0));
        self.view.addConstraint(NSLayoutConstraint(item: imageView, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0));

        // position order constraint
        self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[close(40)]-60-[imageView(150)]-20-[nameLabel(40)]-35-[button(40)]", options: NSLayoutFormatOptions(rawValue:0), metrics: nil, views: ["close" : close,"imageView" : imageView, "nameLabel" : label, "button" : button]));

        //width constaints
        self.view.addConstraint(NSLayoutConstraint(item: button, attribute: .Width, relatedBy: .Equal, toItem: self.view, attribute: .Width, multiplier: 0.5, constant: 0));
        self.view.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Width, relatedBy: .Equal, toItem: imageView, attribute: .Height, multiplier: 1, constant: 0));
        self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[close(60)]-20-|", options: NSLayoutFormatOptions(rawValue:0), metrics: nil, views: ["close" : close]));
    

    override func viewWillAppear(animated: Bool) 
        super.viewWillAppear(false);
        let dSize: CGFloat = min(imageView.frame.height, imageView.frame.width)
        imageView.bounds = CGRectMake(0, 0, dSize, dSize) // centered in container you want to use bounds over frame for this scenario
        imageView.layer.cornerRadius = dSize/2.0
        imageView.layer.masksToBounds = true;
        imageView.layer.borderWidth = 3.0
        imageView.layer.borderColor = UIColor.redColor().CGColor
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func open() 

        if( UIDevice.currentDevice().userInterfaceIdiom == .Pad) 
            self.presentViewController(WebViewController(url: self.person.url), animated: false, completion: nil);
         else 
            self.presentViewController(WebViewController(url: self.person.url), animated: true, completion: nil);
        
    

    func closeView() 
        self.dismissViewControllerAnimated(true, completion: nil);
    


如果我使用框架而不是约束,它会很好地工作,但我想在学习这个时使用约束。

有人能给我指路吗?

提前致谢!

【问题讨论】:

请参考这篇Swift 4+ clean solution 【参考方案1】:

    let dSize: CGFloat = min(imageView.frame.height, imageView.frame.width)
    imageView.bounds = CGRectMake(0, 0, dSize, dSize) // centered in container you want to use bounds over frame for this scenario
    imageView.layer.cornerRadius = dSize/2.0` 

viewWillLayoutSubviews

【讨论】:

viewWillLayoutSubviews是了解视图正确大小的正确位置。【参考方案2】:

Swift 4+

UIImageView 扩展中创建辅助方法,borderWidthborderColor 参数具有默认值

import UIKit

extension UIImageView 

    func setRounded(borderWidth: CGFloat = 0.0, borderColor: UIColor = UIColor.clear) 
        layer.cornerRadius = frame.height / 2
        layer.masksToBounds = true
        layer.borderWidth = borderWidth
        layer.borderColor = borderColor.cgColor
    

示例用法

a) 简单圆角 UIImageView(无边框)

override func viewWillLayoutSubviews() 
        super.viewWillLayoutSubviews()

        self.imageView.setRounded()
    

b) 带有边框宽度和颜色的圆形 UIImageView

override func viewWillLayoutSubviews() 
        super.viewWillLayoutSubviews()

        self.imageView.setRounded(borderWidth: 1.0, borderColor: UIColor.blue)
    

【讨论】:

以上是关于Swift - 带约束的圆形 UIImageView的主要内容,如果未能解决你的问题,请参考以下文章

swift Swift - 在UIView上创建带阴影的圆形图像的扩展

Swift Left Side只有带边框的圆形按钮

UIStackView中的圆形按钮(iOS Swift)

(Swift) 以编程方式将 UIButton 约束到角落

swift – 具有圆角和背景颜色的NSButton

systemLayoutSizeFitting 忽略布局约束并使用图像视图固有大小