Visual changes to UIView don't immediately take effect

Discussion in 'iOS Programming' started by smirk, Oct 7, 2015.

  1. smirk macrumors 6502a

    smirk

    Joined:
    Jul 18, 2002
    Location:
    Orange County, CA
    #1
    Hi, I have a UIView onscreen that was created in a storyboard. At some point in the code (after viewDidLoad), the view's layer.cornerRadius is changed to give it rounded corners. However, the view keeps its square corners until the user taps a button and the contents of the screen are slightly changed. At this point, the view is redrawn with rounded corners.

    What needs to be done to have the UI update itself immediately? myView.setNeedsDisplay had no effect. I know I could put this in viewDidLoad, but I'm trying to understand why things aren't updating as expected.

    Thanks!

    Code:
    myView.layer.cornerRadius = myView.bounds.height / 2.0
    myView.setNeedsDisplay()
    
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    Try

    Code:
    myView.layer.setNeedsDisplay()
    Also, read the CALayer Class Reference from Apple.
     
  3. smirk, Oct 7, 2015
    Last edited: Oct 7, 2015

    smirk thread starter macrumors 6502a

    smirk

    Joined:
    Jul 18, 2002
    Location:
    Orange County, CA
    #3
    Thank you. I will read up more on CALayer. However, myView.layer.setNeedsDisplay() didn't work.

    Any other suggestions?

    Edit: I figured out the problem! The view serves as a colored background to a label. Even though the label has a text value, it appears that it hasn't been rendered yet, and so its superview (`myView`) doesn't yet have a size.

    Is there a way, after assigning a text value to a label, to get it to compute its bounds property?

    Edit #2: Ok, I figured it out:
    Code:
    myLabel.text = "Some words" // myLabel's superview is myView
    myView.setNeedsLayout()
    myView.layoutIfNeeded()
    myView.layer.cornerRadius = myView.bounds.height / 2.0
    
    myView.setNeedsLayout() tells it that something has changed in myView's UI, and myView.layoutIfNeeded() forces myView to lay out its view hierarchy synchronously. Once this has been done, myView.bounds.height actually contains real values.
     
  4. Sean7512 macrumors 6502a

    Joined:
    Jun 8, 2005
    #4

    FWIW, you can set the corner radius in storyboard and that may fix your issue. Also ensure you have proper constraints on your elements so they are sized correctly from the beginning.

    You can add the corner radius in Storyboard by using the "User Defined Runtime Attributes", which is in the "Identity Inspector"

    Hope this helps!
     
  5. smirk thread starter macrumors 6502a

    smirk

    Joined:
    Jul 18, 2002
    Location:
    Orange County, CA
    #5
    Thanks @Sean7512. I've used user defined runtime attributes to do exactly that in the past, but it doesn't appear to accept expressions as values. For what I want, it would have to be self.bounds.height / 2, and I couldn't figure out a way to get IB to accept that.
     
  6. Sean7512 macrumors 6502a

    Joined:
    Jun 8, 2005
    #6
    Ah yes, this way won't work with an expression.

    Did you ever get it working correctly, btw?
     
  7. smirk thread starter macrumors 6502a

    smirk

    Joined:
    Jul 18, 2002
    Location:
    Orange County, CA
    #7
    I did get it working; the explanation is up above in "Edit #2". :)
     
  8. Essenar macrumors 6502a

    Joined:
    Oct 24, 2008
    #8
    Layout "if needed" is pretty low priority.

    I've had my entire view loaded and instantiated for at least 5 seconds before any layout changes would take place, so I would force them to the main thread using async.
    I don't know how to do this in swift but in Objective-C it goes something like:
    Code:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    [get some stuff to use for UI change];
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [do stuff using 'some stuff to use for UI change];
                    });
                });
    
     

Share This Page