tomvanzummeren / TZStackView

UIStackView replica for iOS 7.x and iOS 8.x
MIT License
1.16k stars 128 forks source link

Interface Builder #20

Closed calebd closed 9 years ago

calebd commented 9 years ago

I know your documentation says that this is not supported, but the use of Interface Builder and UIStackView are not mutually exclusive. There is no reason that I shouldn't be able to put a stack view in an Interface Builder document and use it to manage the auto layout constraints I would have had to write otherwise.

tomvanzummeren commented 9 years ago

I see where you're coming from, but I don't exactly understand what would be the benefit to do that. Let me explain why I chose not to support it.

  1. Take a look at this WWDC video explaining how to use a stack view. Skip to ~5:20 for the demo I am talking about. https://developer.apple.com/videos/wwdc/2015/?id=218 - This is the kind of Storyboard support I want, where you can just click two views and press a button to wrap them inside a stack view and adjust the distribution, alignment and axis using the inspector on the right. I cannot make that possible.
  2. The only other way to support Storyboard is to just add a UIView inside Storyboard and then change its class to TZStackView. The problem with this is that the UIStackView (and also my TZStackView, because its a replica) has the notion of "arrangedSubviews" which is a subset of its subviews. So you can add all the subviews you want in Storyboard, they won't automatically become an arranged subview, and for good reason! The reason this separation exists is mentioned in the docs (see Maintaining Consistency Between the Arranged Views and Subviews), and is very simple: ordering. The order in the subviews array determine the Z-index (so which view lays on top of which other view) while the order in the arranged subviews array determine the order in which they are stacked (so which view is positioned beneath or above another view). If I would automatically convert all subviews into arranged subviews (which I would need to do to support Storyboard) you lose the ability to independently configure the Z-index and the actual stack ordering.
  3. This is possibly the most important point: it does not make sense to support Storyboard in the way I described above (so adding a UIView, change its class, add subviews). Why? Because any subview you add will not get positioned by the TZStackView inside Storyboard, only when you run the app. The idea of Storyboard is that what you see is what you get. Doing it like this will absolutely not get you what you see. Even worse: you might be tempted to add your own constraints to make them position correctly. This will screw the whole thing up because they will not be compatible with the auto-generated constraints by TZStackView.

So I'm sorry, as much as I would like to have the same support for Storyboard like you saw in the video, it is just not possible in a way that makes sense. So we just have to be patient until we can make iOS 9 the minimum deployment target of our apps.

calebd commented 9 years ago

There are solutions to all of those problems that are incredibly easy though. There are other (not as nice) stack view libraries that work with IB with no problems.

I am using another library that does all of these things with no problems. I add some views, arrange them how I want with placeholder constraints. The stack view does the real work at runtime. Could not be simpler.

I want to switch to your library because you took the time to properly cover the entire API surface of UIStackView, but sadly you have chosen to not support all the cases that Apple does (IB). So I'll have to stick with the not as good library, or rewrite all of my views with code.

tomvanzummeren commented 9 years ago

You are now contradicting what it says in the docs. I am sure that you can still use subviews and arranged subviews independently in Storyboard in Xcode 7. You can probably drag them above or beneath each other to arrange the arranged subviews and in the left side-pane you can configure the subviews order. It must be something like that, but I didn't check.

And you still didn't address anything related to point 3 which I think is the most important one: you won't see what you get! Stack views are meant to design your entire UI with, to replace 99% of the constraints you normally have to write by hand! If none of the views in your Storyboard are positioned correctly until runtime, what is the point of using Storyboard at all? Just do everything in code then.

But if you are not convinced and still want to work with Storyboard in a crooked way, you are free to change the code yourself. But I stand by Apple's design principles around the stack view. Again check out the docs if you don't believe these principles are real: Maintaining Consistency Between the Arranged Views and Subviews

calebd commented 9 years ago

I mean:

screen shot 2015-08-05 at 1 09 32 am

All views are arranged. Feel free to keep making unsubstantiated claims if you want.

And you are operating under the assumption that I am placing my entire UI in side stack views. I am not. Stack views power part of my hierarchy. The fact remains that both UIStackView and OAStackView let me use IB, your class does not. Do with that what you like.

calebd commented 9 years ago

It doesn't make sense to add anything other than arranged subviews to a stack view. Why would IB make the developer manage which views are installed which way? Both UIStackView and OAStackView just take all views, make them arranged, and preserve their order that is set in IB. It's what Apple does, are they doing it wrong too?

calebd commented 9 years ago

And you still didn't address anything related to point 3 which I think is the most important one: you won't see what you get! Stack views are meant to design your entire UI with, to replace 99% of the constraints you normally have to write by hand! If none of the views in your Storyboard are positioned correctly until runtime, what is the point of using Storyboard at all? Just do everything in code then.

The point is that I replaced hundreds of lines of manual view and constraint building code with a handful of Interface Builder files. I just want to put some stack views in my IB files and know that anything added to them will be managed at runtime.

tomvanzummeren commented 9 years ago

Ok maybe you are not doing everything in stack views. But you could, and I am not making this stack view just for you. I am trying to cover more than just your case. What OAStackView is doing I do not agree with. Try to convince OAStackView of supporting the full API instead then 😉

If what you're saying is true and Storyboard in Xcode 7 does indeed make arranged subviews and normal subviews the same thing, they don't respect the docs and it is probably a bug. Why did they introduce the notion of arranged subviews in the first place then? Unfortunately Storyboard crashes in OSX El Capitan beta 6 so I can't check if this is the case. But I will once it works again.

If you say it just about replacing some code with interface builder files, I would also not recommend that. Interface Builder is about seeing what you're doing. It's actually harder to manage stuff in IB than it is in code: how do you handle Git merge conflicts for example? Where do you have an overview of all your constraints? I see more benefits of having things in code than in Storyboard. The only reason I would use Storyboard for things is to visually see what the UI will look like with different size classes and so on, not to avoid some code. But okay this is a whole other discussion and possibly a matter of taste.

And while you posted three times, you still didn't really address my main point: you don't see what you get it is horrible to see all your views disorganised in Storyboard only to have them automagically organised at runtime. And if you add constraints you will get conflicts with the ones generated by the stack view which is really hard to debug. This is not the way anyone should work with Storyboard/IB.

You're still free to download the code and make the required adjustments yourself. It is not hard to do.

calebd commented 9 years ago

1) My Interface Builder views are not disorganized - they look exactly as they would in the real app 2) I can see all my constraints in the side bar of every Interface Builder file 3) It is not a bug - there is literally no point in adding non-arranged views to a stack view 4) You are clearly not covering all cases that UIStackView does (see: title of this issue) 5) A storyboard is not the only use case for Interface Builder 6) Half the reason of using Interface Builder is to move parts of code into a format that does not need to be maintained by hand 7) You can add constraints in Interface Builder that are placeholders - not compiled into the running app 8) I literally have no constraint conflicts in my app

tomvanzummeren commented 9 years ago

1) How? The constraints are generated at runtime! The only reason could be that you dragged them to the right position (or added the placeholder constraints you mentioned). But you never know for sure that's the spot they will end up 2) Probably a matter of taste but I can't get a good overview of them in my head like that. They also by default have stupid titles that does not make them easily identifiable for me. Also those titles don't update if you edit the constraint. But if it works for you, it works. 3) I agree. But that was not my point. I said that you want to have the control of the z-index (subviews) and order in the stack view (arranged subviews) separate, like Apple designed it. Again, if you treat arranged and the normal subviews as the same thing, why did they have a separate array of arranged subviews then? Also the docs clearly specify the reason, which I explained over and over. But maybe I can explain it by example: What if you have view A, B and C, and you want them ordered A,B,C. The only thing is: A and C need to overlap B a little. You do that by reordering the subviews array to B,A,C and leaving the rearranged subviews A,B,C. I cannot make this any more clear. This is also not something I invented, it is something that is clearly stated in the docs. 4) What I meant by that is that YOU might be very aware of how to use this thing in Storyboard, but that doesn't mean it is intuitive for others. So by "case" I mean the way YOU want to use stack views. I think it is not intuitive if you add views that can be positions way different when you run the app, and if you try to add constraints yourself it breaks. 5) It is to build your interface 6) What do you mean "not by hand". You still have to maintain it by hand! Only non-git-mergeable and hidden beneath all kinds of views with misleading titles. But also, this is a matter of taste and therefore not worth discussing. 7) Adding constraints as placeholders sounds like a hack to me. A quick and dirty workaround. Not the way to go. What is the point? You don't want to add constraints for storyboard, you want to add constraints for your running app only. Otherwise, what's the point. Why use stack view if you still have to add the constraints by hand in IB?? Makes absolutely no sense to me. 8) Yes, YOU don't. But by supporting Storyboard people COULD do it and have no idea what's happening.

To sum up: you totally convinced me that YOU want to do it like this. But I would just not do it like that as I think it is not maintainable and not what Storyboard/IB was meant for. The way it is implemented in Xcode 7 is the way to code, all other attempts that only come close are useless. You found all kinds of workarounds to make it work for you, but it feels like you're trying to create a hammer out of a saw. So I don't want to encourage other people to do it like this by adding support for it.

calebd commented 9 years ago

Like I said a million times, all of those things are supported features of Interface Builder. Literally all of them. If you think they're dumb, go ask Apple to take them out. Just because you don't like it doesn't mean that people don't use those features. Likewise, if you think that the way Apple did stack view subview management in IB is dumb, take it up with them. There's literally no good reason for you to decide that your way is better than the platform supported way. My proposal would work exactly like the real thing, just without the build time preview of your layout. But guess what? It means I would be able to drop it in and use it without rewriting my whole app? Gosh that would be cool.

tomvanzummeren commented 9 years ago

Agreed, I should not let my opinion of IB influence what I do and don't support. And trust me, if I would find a good way to support IB, I would. I just think your proposed solution is not good enough, will cause confusion amongst users of the TZStackView and is against what it says in the docs about arranged subviews being a subset of the subviews and need to be arranged separately. The only good way to support it is how Apple did it in IOS 9: click a button and BAM! your views are wrapped inside a stack view. It is the only way to properly do this in storyboard. I just don't believe in a solution where almost everything you do in IB changes at runtime. If I would need a way to organize my views, I would find another solution for that. Do something clever in code, anything goes. And again: just use OAStackView if you want that kind of support.