0

Just playing around to see if something can be done. I know I can give design-time support to certain properties by adding @IBInspectable to them, and I'm also aware of making the view itself support design-time rendering and display by marking the entire view with @IBDesignable. That all works. What I can't get to work is custom layout support.

Consider this illustrative UIView subclass...

@IBDesignable
public class SimpleStackView : UIView {

    public var spacing:CGFloat = 10 {
        didSet{
            setNeedsLayout()
        }
    }

    @IBInspectable
    public var insets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) {
        didSet{
            setNeedsLayout()
        }
    }

    public override func layoutSubviews() {

        var offset:CGFloat = insets.top

        let visibleSubviews = subviews.filter({ $0.isVisible })
        for view in visibleSubviews{

            let desiredSize = view.intrinsicContentSize

            view.frame = CGRect(
                x      : insets.left,
                y      : offset,
                width  : bounds.width - insets.left - insets.right,
                height : desiredSize.height)

            offset += desiredSize.height + spacing
        }
    }
}

Note: This isn't full-featured--it doesn't calculate its own intrinsic height as an example--but it shows the basics

Adding the above SimpleStackView to a ViewController's main view, pinning all four edges to its container with a spacing of 20, as well as adding three subviews with intrinsic heights of 40, 120 and 80 respectively, you get this as expected...

SimpleStackView Preview

Again, at runtime, this works as expected. What I'm wondering is how I can make this work at design-time (if at all) because this is how it looks at present...

Appearance at DesignTime

Note: The on-screen positions are out of order to the ordinals of the views themselves (i.e. blue is in the middle at runtime, but the bottom at design-time because the design-time isn't properly (or at all!) ordering/laying them out.

I know the normal StackView supports this, but I'm wondering if it's because of the following:

  1. Being designed by Apple, there are specific concessions made in Xcode/IB for it, or...
  2. Being that it's in a separate library (dynamic I believe) and thus is compiled separately, that allows it to run differently.

Both of the above are guesses, but I'd be more inclined to think it's #1.

So can design-time layout support be implemented? If so, how?

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • Since IB is *design-time*, the answer is likely "no". Have you tried overriding theVC's `prepareForInterfaceBuilder()`? It likely won't help, but as you obviously know, it's the best you can do with something meant for "design" and not "run". –  Sep 29 '18 at 18:18
  • Yes, but code *does* run in Interface Builder. Not just `prepareForInterfaceBuilder()` as you pointed out, but also the drawing code, etc. For some reason though, the layout code doesn't seem to run. That's what I'm trying to figure out. No biggie as demonstrated above, it does work at runtime. It's just frustrating that I can't get my layout code to run at design-time. – Mark A. Donohoe Sep 29 '18 at 19:54
  • Do you remember when things were (a) totally separate apps, (b) working with struts and springs, and (c) there was no such thing as auto layout? Maybe your wish will come true when Xcode 14 is released! –  Sep 29 '18 at 23:47
  • Oh... I *MUCH* prefer AutoLayout! It's so incredibly flexible and powerful. I just wish that Xcode worked like Visual Studio did on the Windows side where the IDE would run things like this. It's a limitation of the tool, not the technology it facilitates. – Mark A. Donohoe Sep 30 '18 at 00:32
  • Being old school, I do my constraints in code - I like a different layout for landscape versus portrait, and even Apple (in a WWDC'17 session) did as much because (huh?) iPads have the same size class unless if a multi-task split screen is used. I semi-retired in 2016 and left my VS (they changed the name?) behind after years of only coding console projects for servers. My only real knowledge with "Windows mobile" is that it's not large. And yeah, my macOS experience with auto layout is non-existent (a reason I stick to iOS). With resizable windows, I'd think most macOS apps stick with frames? –  Sep 30 '18 at 01:13

0 Answers0