For instance, being able to set the constraint "element.[x,y] = other.[x,y]+other.[width,height]/2;", instead of working with "attachment" objects.
For instance, being able to set the constraint "element.[x,y] = other.[x,y]+other.[width,height]/2;", instead of working with "attachment" objects.
It's powerful but not trivial to adopt. In particular, the design experience in Interface Builder has gone backwards in usability. The old system of resizing rules visualized as "springs and struts" was easier to understand in a visual design tool.
One might argue that's the cost of progress, and that designers using Interface Builder become better UI engineers when they have to figure out how to express themselves in constraints. But it seems to me that the reality is that a lot of people just stopped using IB.
IB used to be a crown jewel of NeXT's development suite in the 1990s. It was simple and focused, and allowed you to build surprisingly powerful UIs that connected to high-performance native code (unlike its mainstream competitor Visual Basic).
I don't think a lot of people have such fond feelings about Apple's current IB. Something was lost along the way.
I wonder how we can stimulate "expert" tools and systems for those who don't want to take the greedy path of least resistance, and are tired of painting themselves into corners that way.
My learning path went something like this:
(The dark ages of data processing for personal use)
- Use a text file: Fine, you have to write your own read & write logic, but for small amounts of data this works.
- Use a CSV file: less custom logic than plaintext
- Use a JSON file: really nice to have structured data!
- Use a Python pickle file: the idea is you can “pick up where you left off”, but it’s slow, clunky, and inflexible
(Finally learning to use a database)
- Use Google Sheets: oh, it’s nice to be able to index things without needing to read/write the entire dataset! You can also do searches and stuff, it’s great.
- Django ORM + MongoDB: Oh my god, so horrible. MongoDB was supposed to be simple. This set up was slow and complicated. Migrations were a constant pain. And we didn’t even have any users.
- Postgres: It all makes sense. SQL is great. You can think about and query your data in reasonable ways. And it’s fast.
- DynamoDB: Yeah whatever, as long as you do validation on every read/write you’ll probably be fine.
I always thought that Apple should have really pushed the whole "Applescript Studio" thing so as to create something even better and more approachable than Visual Basic --- it could have been a true HyperCard replacement.
First, expectations and requirements went up. Laying stuff out with a mouse and snap-to alignment guides is ok for simple UI, but the more complex the design, the more I would end up fighting the vector-art style design interface. I remember staying up late fixing pixel alignment errors in nib files. Often you would need to move objects around to inspect another underneath and then play undo games to get things back exactly where they were.
The interesting parallel here is that the designers were doing all the designs in vector art apps, and were also frequently missing dynamic aspects of the design requirements.
It was one thing to design complex dialog boxes for desktop; think of a photoshop filter control pane. You target a minimum size screen, and then work with a fixed pane and lay things out. When the iPhone came out, IB worked ok for early versions and stock components. Screens were crowded but fixed width.
Once bigger screens came out, more designs started needing variable width layout computation. The APIs for dynamic layout were (as I recall now) more subtle than they sounded in the docs, and I recall joining several teams that misused them. “sizeToFit” and “sizeThatFits” were two culprits. Perhaps it made more sense in the simpler NeXT days, and perhaps the docs degraded. If you didn’t read Apple’s “Programming Guide” docs, it was hard to know how these things were supposed to work together, and those were like mini books. The guides got increasingly ignored as the iPhone’s UIKit took center stage. I was always a fan of NSAutoresizingMaskOptions but rarely saw others use them.
Second, modern version control made the binary nib files unmanageable, and merging the xml xib files was also awful.
Third, and to the parent comment’s point, there were quality problems with Interface Builder. New stuff got heaped on every year. The data model was proprietary but looking at the xml clearly just got more complicated and version-encumbered over time.
In summary, it is tempting to glorify the original NeXT tools, but I never used them. I started toying with IB in 2004. It never felt like a brilliant system because I couldn’t express the underlying logic of designs in the visual box dragging paradigm. Ironically auto layout pushed me further towards UI in code. But to each their own.
Did you make any progress on this for macOS or iOS/iPadOS?
Out of total hatred of Xcode and Interface Builder I started experimenting with writing Apple UI stuff in C (calling Cocoa methods through libobjc), but there's precious few resources on doing so-called "Nibless/Xibless" development beyond the basics.
I'd love to find a decent-sized open-source macOS app written in [Objective-]C/C++ but with a good assortment of common UI paradigms, all done in code. I shudder whenever I see that dreaded .xcodeproj directory...
I suspect that this is because the average Mac window/view nib file is a great deal less complex than its counterpart view nib on iOS and still manageable to edit in Interface Builder, and so a lot of Mac devs still use nibs.
I've toyed with code-only Mac AppKit stuff but generally have found that it's not quite as clean as code only iOS UIKit. For example if I recall correctly, there's no initializer for NSWindow that sets all of the flags that make it behave like a normal window because it's assumed that you'll be using nibs. It's not difficult to write an extension to NSWindow to fix this, but it has to be done for reasonable productivity, and these papercuts are strewn throughout AppKit. In contrast, most UIKit controls can be initialized with few or no arguments and still behave as expected.
Thanks for the suggestion! Any others you can think of?
This seems to have originated in something called Visix Galaxy, and supposedly done better there than in Interface Builder. See here: https://wiki.c2.com/?SpringsAndStruts
I tried finding any documentation on this tool/SDK, but no luck. Any one else has any more information on what this Galaxy looked like?
it's awesome for small things (like mobile-style app GUIs), but not usable for full-scale desktop apps (e.g. a DAW).
but that's a question of performance. 'maintainability' would be removing the code that adds the row to the list, which is trivial with cassowary
I'd love something like this:
red-box {
width: 100
height: 100
top: 10
left: 10
}
blue-box {
width: 50
height: 50
top: $red-box.bottom * 2
left: $red-box.right + 100
}I think flexbox and grid handle a good chunk of what you'd want here, but having to handle constraints at the "group" level. Either flexbox, so the browser finds the best way to place elements into a line based on your rules, or grid for 2 dimensions:
boxes {
display: grid;
/* there are only 2 columns, 100px each */
grid-template-columns: 100px 100px;
/* all rows are 100px tall */
grid-auto-rows: 100px;
> * {
/* All children take up 1 col, and 1 row */
grid-column-end: span 1;
grid-row-end: span 1;
}
}
blue-box {
/* blue-box must start at col #2 and row #2 */
grid-column-start: 2;
grid-row-start: 2;
}The problem with this specific API is that it depends on source order. To have element-b anchored to element-a, element-a must come first in source. I'm not really sure if it was designed that way or just implemented that way in Chrome, but it's the behavior I experienced when I played around with it.
Currently we are detecting mobile based on a JS library and branching the template based on that, which I abhor. Using Tailwind’s media prefixes and some data- group selectors, I’ve gotten a rough version working with just two small JS listeners to toggle the open state.
I think you could apply group rules to target a specific child or sibling in such a way that you can apply specific rulesets, and maybe CSS variables to dynamically base those on sibling values.
btw, gtk is based on tcl/tk which i believe is the, or one of the, original auto layout engines