Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILabel text property when set to nil or "" makes UILabel disappear from view (Swift / Autolayout/ iOS9.1)

Tags:

ios

uilabel

swift

I am going through the Stanford Winter 2015 Swift/iOS course and while doing the assignments I run into a behavior I'd like to change.

I use Autolayout as described in the videos (making the display pin to leading and trailing view edges) and the Calculator app "Display" UILabel is fine with an initial value of 0 and whenever the value used to set it (a String) is non-nil and non "".

If it is either nil or "", the entire UILabel disappears. What I am trying to do is to "clear" the display whenever there is no value to display or an incorrect calculation resulted in nil.

Any tips on who to deal with this in general? "Clearing" a UILabel without changing it's on-screen dimensions?


Edit (thanks Rob) The UILabel has the following constraints 1. Option-click drag-left to containing UIView, selected "leading" something (on commute to work can't check yet for exact wording. 2. Same method as (1) except that the drag is to the right edge and selecting "trailing" 3. Option click-drag up to top of view, select "vertical" menu option. 4. Same as (3) except that drag is to a UIButton underneath the UILabel on the GUI.

With those settings, the label when it contains a number is always visible and (if understand, will color it to verify) stretches across the screen even if the text doesn't.

The layout looks correct in profile and landscape as long as content of UILabel is not empty. If empty, it seems to "shrink to fit" so much that the buttons below get moved up towards the top.

I'm a C++ dev since mid 90s but I have little UI experience and no more than a couple weeks experience in iOS/Swift development.

Thanks!

like image 851
Varsuuk Avatar asked Oct 28 '15 04:10

Varsuuk


2 Answers

You can always give the UILabel a min width and min height or constraints that holds the left and right side of the label. That should keep the label from changing it's dimensions to zero.

like image 157
Moriya Avatar answered Oct 15 '22 11:10

Moriya


Use a custom UILabel class assigned in Interface Builder >> Identity inspector >> Custom Class >> Class to override UILabel intrinsic content size.

No need to create any superfluous auto-layout constraints.

Swift:

class UILabelNonCompressible: UILabel
{
    private static let NonCompressibleInvisibleContent = " "

    override var intrinsicContentSize: CGSize
    {
        if /* zero-width */ text == nil ? true : text!.isEmpty
        {
            // prefer mirror-and-calculate over modify-calculate-restore due to KVO
            let doppelganger = createCopy()

            // calculate for any non-zero -height content
            doppelganger.text = UILabelNonCompressible.NonCompressibleInvisibleContent

            // override
            return doppelganger.intrinsicContentSize
        }
        else
        {
            return super.intrinsicContentSize
        }
    }
}

You will also need "How do copy for UILabel?":

extension UILabel
{
    func createCopy() -> UILabel
    {
        let archivedData = NSKeyedArchiver.archivedData(withRootObject: self)
        return NSKeyedUnarchiver.unarchiveObject(with: archivedData) as! UILabel
    }
}
like image 29
Gary Avatar answered Oct 15 '22 12:10

Gary