【问题标题】:XIB view not showing with correct layout [iOS Swift]XIB 视图未以正确的布局显示 [iOS Swift]
【发布时间】:2018-11-09 17:40:51
【问题描述】:

我正在尝试制作自定义警报视图,但由于显示的视图正在切割视图的下半部分这一事实,我面临一些问题(下图)

显示方式:

期望的输出:

所以基本上,我有一个名为 CustomAlertView 的 XIB,由一个带有 init 的同名类支持,如下所示:

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

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

private func commonInit() {
    Bundle.main.loadNibNamed("CustomAlertView", owner: self, options: nil)
    contentView.frame = self.bounds
    contentView.translatesAutoresizingMaskIntoConstraints = true
    addSubview(contentView)
    //contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

}

我有另一个类负责使用 customAlertView 创建警报 CustomAlert。这个 CustomAlert 类正在使用以下代码创建 backgroundViewdialogView(我正在尝试将我的 customAlertView 添加到其中):

func initialize(title:String, description:String){
    dialogView.clipsToBounds = true

    backgroundView.frame = frame
    backgroundView.backgroundColor = UIColor.black
    backgroundView.alpha = 0.6
    backgroundView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTappedOnBackgroundView)))
    addSubview(backgroundView)

    dialogView.frame.origin = CGPoint(x: 0, y: 0)
    dialogView.frame.size = CGSize(width: frame.width-32, height: frame.height/3)

    dialogView.backgroundColor = UIColor.white
    dialogView.layer.cornerRadius = 6

    let alertView = CustomAlertView.init(frame: self.bounds)
    alertView.titleLabel.text = title
    alertView.descriptionLabel.text = description
    alertView.cancelButton.backgroundColor = UIColor.brown

    dialogView.addSubview(alertView)


    addSubview(dialogView)
}

我认为我对框架和边界感到困惑,但找不到解决方案。

我希望将所需的输出完美地放置在 dialogView 中。

编辑

CustomAlert 中我的 .show 函数的代码

func show(animated:Bool){

    self.backgroundView.alpha = 0
    self.dialogView.center = CGPoint(x: self.center.x, y: self.frame.height + self.dialogView.frame.height/2)
    UIApplication.shared.delegate?.window??.rootViewController?.view.addSubview(self)
    if animated {
        UIView.animate(withDuration: 0.33, animations: {
            self.backgroundView.alpha = 0.66
        })
        UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 10, options: UIViewAnimationOptions(rawValue: 0), animations: {
            self.dialogView.center  = self.center
        }, completion: { (completed) in

        })
    }else{
        self.backgroundView.alpha = 0.66
        self.dialogView.center  = self.center
    }
}

Github 链接git-alert-view

【问题讨论】:

  • 为什么不使用自动布局在视图控制器中添加警报?
  • 我不确定您在视图控制器中使用自动布局是什么意思。在我的视图控制器中,我只是创建了传递标题和描述的警报,以及一个 .show(将 dialogView 设置为中心)
  • 能否请您添加您的 show() 方法的代码?
  • 在您的初始化方法中,您不会像在第一个代码块中显示的那样初始化 CustomAlertView。我认为你应该通过 nib 加载它。
  • 我编辑了第一个块代码,我想现在更清楚了,抱歉混淆了....我实际上在 init 中加载了 nib

标签: ios swift uiview autolayout xib


【解决方案1】:

对于和我遇到同样困难的人来说,我能够完成想要的结果。

我按照@HAK 的建议使用了自动布局。但我没有编写自己的 NSLayoutConstraint,而是使用了名为 TinyConstraints 的 roberthein 库。

基本上,我使用如下:

代替

NSLayoutConstraint.activate([
alertView.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0),
alertView.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0),
alertView.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0),
alertView.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 
0)])

使用 TinyConstraints:

alertView.edges(to: superview)

就是这样

【讨论】:

    【解决方案2】:

    像这样更改您的 CustomAlertView:

    class CustomAlertView: UIView {
    
        @IBOutlet weak var titleLabel: UILabel!
        @IBOutlet weak var descriptionLabel: UILabel!
    
        @IBOutlet weak var confirmButton: UIButton!
        @IBOutlet weak var cancelButton: UIButton!
    
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        static func customAlert() -> CustomAlertView {
            return Bundle.main.loadNibNamed("CustomAlertView", owner: self, options: nil)!.first as! CustomAlertView
        }
    
    }
    

    您的 CustomAlert 的初始化方法如下:

    func initialize(title:String, description:String){
        dialogView.clipsToBounds = true
    
        backgroundView.frame = frame
        backgroundView.backgroundColor = UIColor.black
        backgroundView.alpha = 0.6
        backgroundView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTappedOnBackgroundView)))
        addSubview(backgroundView)
    
        dialogView.frame.origin = CGPoint(x: 0, y: 0)
        dialogView.frame.size = CGSize(width: frame.width-32, height: frame.height/3)
    
        dialogView.backgroundColor = UIColor.white
        dialogView.layer.cornerRadius = 6
    
        let alertView = CustomAlertView.customAlert()
        alertView.titleLabel.text = title
        alertView.descriptionLabel.text = description
        alertView.cancelButton.backgroundColor = UIColor.brown
    
    
        dialogView.addSubview(alertView)
    
        addSubview(dialogView)
    
    }
    

    在 CustomAlertView xib 中: 1. 选择文件所有者并删除类(默认为 NSObject)。 2. 选择文件所有者,然后删​​除所有出口。 3. 选择您的内容视图并将其指定为 class= CustomAlertView。 4. 选择您的 CustomAlertView 并进行所有插座连接。

    最终版本:

    你有一个工作警报:

    PS:相应调整 UI。

    【讨论】:

    • 也没用,我附上github链接,方便看代码
    • @RaphaelHenrique 在您的存储库中创建了拉取请求。您可以从那里获取代码。
    • 谢谢@HAK,这种方法的问题是我被我的xib文件的高度和宽度所困扰,它必须是一定的大小。我正在寻找一种解决方案,它独立于我的 xib 文件的大小,它填充所有对话框视图(底部有按钮,中间有描述等)
    • 为此您需要使用自动布局。
    • 在这种情况下如何使用自动布局?在 xib 中,一切都是响应式的
    【解决方案3】:

    在你的 xib 类中添加这个:

    override func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()}
    
    func xibSetup() {
        guard let view = loadViewFromNib() else { return }
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }
    

    参考来自:https://medium.com/zenchef-tech-and-product/how-to-visualize-reusable-xibs-in-storyboards-using-ibdesignable-c0488c7f525d#.3c0javomy**

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2019-06-24
      • 2018-06-06
      相关资源
      最近更新 更多