ios - 更新自动布局约束以重新定位文本字段

标签 ios swift uitextfield nslayoutconstraint ios-autolayout

我目前正在努力完成 Udacity iOS 开发纳米学位,遇到了一个我真的很难解决的问题。我是开发和 Stackoverflow 的新手,所以这是我的第一篇文章……开始吧;

我正在构建一个用于生成模因的应用程序。它通过允许用户选择图像并输入一些文本来实现这一点。

我有一个 UIView。在那个 UIView 中,我有 2 个 UIToolbar、2 个 UITextField 和一个 UIImageView。工具栏位于 View 的顶部和底部,文本字段分别位于它们下方和上方。 UIImageView 占满了 View 的宽度和高度,位于工具栏和文本输入的下方。

请在此处查看 screenshots of Storyboard and app

用户可以从他们的相册中选择一张图片,或者用他们的相机拍照,以填充 UIImageView。然后将 UIImageView 设置为 Aspect Fit 以保持其正确的纵横比。

我在 Interface Builder 中设置了约束,以便 UITextFields 位于与顶部和底部工具栏的恒定距离处。

我遇到的问题是用户需要旋转设备来定位文本字段,以便它们位于图像的顶部和底部。我的意思是,如果用户选择横向图像,而设备是纵向的,则用户需要旋转他们的设备以确保文本字段位于图像的顶部。

我想做的是在用户选择或拍摄图像并且图像已应用 Aspect Fit 后重新定位 textFields。

有人建议我可以使用 AVMakeRectWithAspectRatioInside 来生成一个 CGRect,在它具有 Aspect Fit 之后,它具有与 UIImage 相同的尺寸应用后,使用 CGRect 更新 UIImageView 的框架,然后更新约束。

我已经设法生成了新的 CGRect 并更新了 UIImageView 的框架。然后我更改了对 UITextFields 的约束,以便它们与 UIImageView 而不是工具栏对齐,但是当 UITextFields 不重新定位时框架已更新。

我在更新框架后调用以下命令;

view.setNeedUpdateConstraints()

如果有人知道解决这个问题的最佳方法,那就太好了。

编辑:

这是我创建的项目中 viewController 的代码,用于隔离并尝试解决此问题..

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var imageViewPic: UIImageView!
    @IBOutlet weak var topTextToToolberContraint: NSLayoutConstraint!
    @IBOutlet weak var bottomTextToToolbarConstraint: NSLayoutConstraint!
    @IBOutlet weak var topText: UILabel!
    @IBOutlet weak var bottomText: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(animated: Bool) {
        let imageToDisplay = UIImage(named: "Captain-Picard-Facepalm")
        imageViewPic.image = imageToDisplay
    }

    func updateFrame() {        
        let resizedImageSize = imageViewPic.image!.size
        let imageViewBounds = imageViewPic.bounds
        let newRect = AVMakeRectWithAspectRatioInsideRect(resizedImageSize, imageViewBounds)
        imageViewPic.frame = newRect
    }

    override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
        updateFrame()
        view.setNeedsLayout()
    }
}

最佳答案

我发现这里的问题是绘制/渲染 View 。所以诸如 View 之类的东西在实际布局发生之前绘制,这意味着在 View 未呈现之前框架不会改变。

您在这里可以做的是在实际绘图发生之前尽早强制布局。有一种方法可以在 View 的框架更新时处理强制布局 View 。

func setNeedsLayout()
func layoutIfNeeded()

以上两种方法都用于强制布局 View 。

试试下面的代码,它可以负责更新布局。

func updateFrame() {        
    let resizedImageSize = imageViewPic.image!.size
    let imageViewBounds = imageViewPic.bounds
    let newRect = AVMakeRectWithAspectRatioInsideRect(resizedImageSize, imageViewBounds)
    imageViewPic.frame = newRect
    imageViewPic.layoutIfNeeded()
    self.view.layoutIfNeeded()
}

同时覆盖 ViewController 中的以下方法。 updateViewConstraints() 方法用于更新自定义约束。

override func updateViewConstraints() {
    super.updateViewConstraints()
    self.view.layoutIfNeeded()
    self.imageViewPic.layoutIfNeeded()
}

关于ios - 更新自动布局约束以重新定位文本字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32479499/

相关文章:

ios - Branch.io 统计数据

ios - Xcode 12 SwiftUI 应用程序因 UIRequiredDeviceCapabilities plist 键而被拒绝

ios - pubnub显示消息“无法保存转储”是错误吗?如果没有,如何将其静音?

ios - CollectionView 单元格在选中时移动

swift - 如何删除 Collection View 中的部分

ios - 仅在 iOS 6 上使用特定字体剪辑的标签和文本字段文本

ios6 - UITextField autocapitalizationType UITextAutocapitalizationTypeAllCharacters 在设备上不起作用

ios - CoreData iOS App的Sqlite文件位置的位置

ios - 使用 mapkit 信息按钮推送到第二个 View Controller

ios - TextField 覆盖在 ScrollView 上 "Adjust to Fit"TextField 不起作用