具有UIImageView的子类UIView内部没有响应自动布局

时间:2017-01-13 13:33:31

标签: ios swift uiview

我正在尝试创建一个UIView,其UIImage属性设置为2 UIImageView。我正在尝试创建的效果是一个配置文件视图,并在故事板中工作:

Profile View

然而,在我的应用程序中,它不响应自动布局。在菜单中实例化的那一刻,视图溢出了菜单视图控制器:

enter image description here

import UIKit

@IBDesignable
class ProfileImageView: UIView {

    @IBInspectable
    var profileImage : UIImage = UIImage()

    @IBInspectable
    var topImageScalePercentage : CGFloat = 50

    override init(frame: CGRect) {
        super.init(frame: frame)
        updateLayout()
    }

    convenience init() {
        self.init(frame: CGRect.zero)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        updateLayout()
    }

    func updateLayout() {

        // Create the large background Image View
        let blurredProfileView = UIImageView(frame: self.bounds)
        blurredProfileView.image = profileImage
        blurredProfileView.contentMode = UIViewContentMode.scaleAspectFill
        blurredProfileView.layer.masksToBounds = true

        // Blur the background Image View
        let blurEffect = UIBlurEffect(style: .light)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.frame = blurredProfileView.bounds
        blurredProfileView.addSubview(blurView)

        // Add the Blurred Profile View to view
        self.addSubview(blurredProfileView)

        // Create smaller Profile Picture
        var profileRect : CGRect!
        if blurredProfileView.bounds.width < blurredProfileView.bounds.height {
            let width = blurredProfileView.bounds.width * topImageScalePercentage / 100.0
            let height = width // 1:1
            profileRect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
        } else {
            let height = blurredProfileView.bounds.height * topImageScalePercentage / 100.0
            let width = height // 1:1
            profileRect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
        }
        let profileImageView = UIImageView(frame: profileRect)
        profileImageView.image = profileImage
        profileImageView.contentMode = .scaleAspectFill
        profileImageView.layer.masksToBounds = true
        profileImageView.layer.cornerRadius = profileImageView.bounds.width / 2
        profileImageView.center = blurredProfileView.center

        self.addSubview(profileImageView)

    }
}

3 个答案:

答案 0 :(得分:2)

您正在混合自动布局和基于帧的布局,并期望在您的视图移动或调整大小时帧自动更新。这不会发生。

尝试将视图限制到适当的位置,如:

func updateLayout() {

    // Create the large background Image View
    let blurredProfileView = UIImageView(image: profileImage)
    blurredProfileView.contentMode = UIViewContentMode.scaleAspectFill
    blurredProfileView.layer.masksToBounds = true

    self.addSubview(blurredProfileView)
    blurredProfileView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    blurredProfileView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    blurredProfileView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    blurredProfileView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    blurredProfileView.translatesAutoresizingMaskIntoConstraints = false


    // Blur the background Image View
    let blurEffect = UIBlurEffect(style: .light)
    let blurView = UIVisualEffectView(effect: blurEffect)

    blurredProfileView.addSubview(blurView)
    blurView.leftAnchor.constraint(equalTo: blurredProfileView.leftAnchor).isActive = true
    blurView.rightAnchor.constraint(equalTo: blurredProfileView.rightAnchor).isActive = true
    blurView.topAnchor.constraint(equalTo: blurredProfileView.topAnchor).isActive = true
    blurView.bottomAnchor.constraint(equalTo: blurredProfileView.bottomAnchor).isActive = true
    blurView.translatesAutoresizingMaskIntoConstraints = false



    // Create smaller Profile Picture
    var profileRect : CGRect!
    if blurredProfileView.bounds.width < blurredProfileView.bounds.height {
        let width = blurredProfileView.bounds.width * topImageScalePercentage / 100.0
        let height = width // 1:1
        profileRect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
    }
    else {
        let height = blurredProfileView.bounds.height * topImageScalePercentage / 100.0
        let width = height // 1:1
        profileRect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
    }

    let profileImageView = UIImageView(image: profileImage)
    profileImageView.contentMode = .scaleAspectFill
    profileImageView.layer.masksToBounds = true
    profileImageView.layer.cornerRadius = profileRect.width / 2

    self.addSubview(profileImageView)
    profileImageView.centerXAnchor.constraint(equalTo: blurredProfileView.centerXAnchor).isActive = true
    profileImageView.centerYAnchor.constraint(equalTo: blurredProfileView.centerYAnchor).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: profileRect.width).isActive = true
    profileImageView.heightAnchor.constraint(equalToConstant: profileRect.height).isActive = true
    profileImageView.translatesAutoresizingMaskIntoConstraints = false
}

答案 1 :(得分:0)

如上所述here,如果您打算使用自动布局

,则不应操纵帧

答案 2 :(得分:0)

如果您要更新子视图/图层的帧/图层,则只能在自动布局完成其帧计算后执行此操作,即覆盖layoutSubViews并移动您的帧代码。或者使用自动布局。由于您只想填写超级视图,因此可以使用以下扩展名:

    extension UIView {
        func constrainToSuperView() {
            translatesAutoresizingMaskIntoConstraints = false
            let attributes: [NSLayoutAttribute] = [.centerX, .centerY, .width, .height]
            NSLayoutConstraint.activate(attributes.map{NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: self.superview, attribute: $0, multiplier: 1, constant: 0)})
        }
    }