简体   繁体   中英

Get UIView frame using autolayout after http request

I still don't understand how I should get the updated frame of a UIView , when using autolayout.

Let's say I:

  1. Setup some views using autolayout.
  2. Make an HTTP request to get some data.
  3. When I get the data, I want to draw it but I need the updated frame size of a view.

How should I go about it?

My guess, but it's wrong:

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)
}

Here's just an example UIViewController - you can start your call in view did load and block the ui or at least indicate activity and then when that call completes you can update the UI based off of whatever current view properties you'd like.

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) {
}
}

This is more or less what I'm doing right now. If anyone can suggest a better alternative please post or comment about it.

As you will see, in drawDataIfPossible() I check that both the data is set and the frame size is set. I check both because drawDataIfPossible() is called from these two functions:

  1. drawData(data: MyData) , which might be called before the frame size is set
  2. layoutSubviews() , which might be called before the data is set.

.

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()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM