【问题标题】:Get UIView frame using autolayout after http requesthttp请求后使用自动布局获取UIView框架
【发布时间】:2016-07-01 16:59:27
【问题描述】:

在使用自动布局时,我仍然不明白如何获取 UIView 的更新帧。

假设我:

  1. 使用自动布局设置一些视图。
  2. 发出 HTTP 请求以获取一些数据。
  3. 获得数据后,我想绘制它,但我需要更新后的视图帧大小。

我应该怎么做?

我的猜测,但它是错误的:

layoutMyViews()
makeHttpRequest(callback)

func callback(data: MyData) {
    drawData(data, into:dataView)
}

func drawData(data: MyData, into view:UIView) {
    let size = view.frame.size
    // Here I want to draw data into view, depending on size, but it may be (0,0)
}

【问题讨论】:

  • 什么是drawData?除非您重新加载现有的 API 类,例如 tableview,否则您需要手动更新视图以容纳数据,此时您应该知道它的大小。
  • drawData() 是我想在view 中添加一些内容的地方(我在上面添加了一个示例),但我需要设置view.frame.size。我该怎么做?
  • 如果你使用自动布局,它已经设置好了
  • 使用自动布局,您可以设置约束,但之后会计算帧。如果尚未计算帧,我猜大小可能为 0。
  • 加载视图后,您可以访问它的框架。因此,如果您从 viewDidLoad 或在 UIViewController 视图的生命周期上下文中调用您的方法,您可以通过调用 view.frame.size 来访问它的框架属性。

标签: ios swift layout autolayout


【解决方案1】:

这只是一个 UIViewController 示例 - 您可以在视图中开始调用并阻止 UI 或至少指示活动,然后当该调用完成时,您可以根据您想要的任何当前视图属性更新 UI。

class ViewController: UIViewController {

// You can start accessing view properties from the storyboard here.
override func viewDidLoad() {
    super.viewDidLoad()
    print(self.view.frame) // Outputs the frame of the view controller's view.
    // Do any additional setup after loading the view, typically from a nib.
}

override func viewDidLayoutSubviews() {
}

override func viewWillAppear(animated: Bool) {
}

override func viewDidAppear(animated: Bool) {
}
}

【讨论】:

  • 我想要视图的框架,而不是视图控制器的框架。无论如何,即使是视图控制器的框架在那个阶段也可能是错误的。这是题外话,但你可以检查一下:stackoverflow.com/a/16796881/1121497
  • 框架依赖于约束,视图加载后框架被加载。如果您在情节提要的视图控制器上使用子视图,这对它们也是如此。
  • 这是一个很好的链接,如果您在这些方法中更新您的视图,您当然应该在需要时检查它们的新值。无论哪种方式,只需在创建视图时调用您的任务并根据需要进行更新。
【解决方案2】:

这或多或少是我现在正在做的事情。如果有人可以提出更好的替代方案,请发表或评论。

正如您将看到的,在drawDataIfPossible() 中,我检查了data 是否已设置,帧大小是否已设置。我检查了这两个函数,因为drawDataIfPossible() 是从这两个函数中调用的:

  1. drawData(data: MyData),可能在设置帧大小之前调用
  2. layoutSubviews(),可能会在设置 data 之前调用。

.

class Controller : UIViewController {

    // Here I will draw some data that comes from server
    var dataView: MyDataView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Here I add the views using autolayout, including dataView
        layoutMyViews()

        // Here I make the http request to get data
        makeHttpRequest(callback)
    }

    /** When the data comes, I tell the dataView to draw itself */
    func callback(data: MyData) {
        dataView.drawData(data)
    }

    //...
}

class MyDataView : UIView {

    var data: MyData!

    /** Draws the data in the view */
    func drawData(data: MyData) {
        self.data = data
        drawDataIfPossible()
    }

    func drawDataIfPossible() {
        // Here I check I have the data and that the frame size is set
        if data != nil && frame.size.width > 0 {
            drawData()
        }
    }

    /** Draws data in the view (needs the frame size) */
    func drawData {
        // ...
    }

    override func layoutSubviews()
    {
        super.layoutSubviews()
        layoutIfNeeded() // seems to be necessary for the frame size to be set
        drawDataIfPossible()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-12
    • 2022-01-21
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多