iosxcodedebugging

How do I change names programmatically to tell apart UIViews in Xcode visual debugger?


How do I rename views in Xcode visual debugger? It's a sea of UIViews so it's nearly impossible to tell which uiview a constraint is for.

UIViewControllers show titles while for UIViews unless it's a derived class it's UIView. How do you tell them apart?

Case to the point

enter image description here

this seems to be a duplicate of How to set the Identifier of a UIView in Xcode 4.5/iOS for debugging auto layout?


Solution

  • Control-click the view in question and choose Print Description in the contextual menu:

    <UIView: 0x7fbec8508420; frame = (30 34; 163 117); autoresize = RM+BM; 
        layer = <CALayer: 0x6000019c65c0>>
    

    Often that will be enough to identify the view. If it isn't, you can ask the view questions, though the syntax is a little tricky:

    (lldb) expr -l objc -O -- [(UIView*)0x7fbec8508420 backgroundColor]
    <UIDynamicModifiedColor: 0x6000017c6f10; contrast = normal, 
        baseColor = <UIDynamicSystemColor: 0x6000019c6600; name = systemYellowColor>>
    


    Another trick I sometimes use is to give the view an identifier. A little-known trick is that a layer has a name that you can use as you like. And a view has a layer. So I declare an extension:

    extension UIView {
        @objc var name : String? { return layer.name }
    }
    

    Now you can ask the view for its name. You can assign the name in code or (using runtime attributes) in the storyboard.


    My technique for giving a view a name and seeing it in the view debugger has a evolved a bit since I originally gave this answer, so I want to show what it looks like now:

    extension UIView {
        @objc var debugName: String {
            get { layer.name ?? "" }
            set { layer.name = newValue }
        }
        open override var debugDescription: String {
            var proposedDescription = description
            if !debugName.isEmpty {
                proposedDescription.insert(
                    contentsOf: "; name = '\(debugName)'",
                    at: proposedDescription.index(proposedDescription.endIndex, offsetBy: -1)
                )
            }
            return proposedDescription
        }
    }
    

    The reason this is cool is that the debug name is shown automatically in the Xcode console during view debugging when you Print Description. I can't begin to describe how useful that is. Together with constraint identifiers, you can easily work out exactly what's going on.