{"id":36502,"date":"2022-07-13T15:51:52","date_gmt":"2022-07-13T19:51:52","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=36502"},"modified":"2024-02-27T10:41:49","modified_gmt":"2024-02-27T15:41:49","slug":"interfacebuilder-swift","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2022\/07\/13\/interfacebuilder-swift\/","title":{"rendered":"InterfaceBuilder.swift"},"content":{"rendered":"<p><a href=\"https:\/\/inoads.com\/articles\/2022-07-13-Interface-Builder\">Maximilian Mackh<\/a> (<a href=\"https:\/\/twitter.com\/mmackh\/status\/1547183816086790144\">tweet<\/a>):<\/p>\n<blockquote cite=\"https:\/\/inoads.com\/articles\/2022-07-13-Interface-Builder\">\n<p>InterfaceBuilder.swift lets you quickly build complex UIKit layout in code, speed up native app development and is completely open source.<\/p>\n<p>[&#8230;]<\/p>\n<p>The SwiftUI approach to layout in code is objectively fantastic and has inspired many aspects of this library. On the flip side, actual SwiftUI layout behaviour is very similar to self-sizing elements in HTML and abstracts many complexities to the underlying mystery layout engine. As with HTML, minor changes to the engine result in widely different layout behaviour. Whether this approach makes sense or not is debatable, but one thing is for certain: iOS has not (initially) been designed for, or particularly good at, self-sizing. In conjunction with several ways to cause unexpected redraws through Combine, it&rsquo;s no wonder performance remains an issue.<\/p>\n<p>[&#8230;]<\/p>\n<p>Since SwiftUI (plus new APIs) come bundled with OS releases, this is a recipe for broad range of inconsistencies.<\/p>\n<\/blockquote>\n\n<p>The name &ldquo;InterfaceBuilder&rdquo; is apt because it&rsquo;s replacing the Interface Builder part of Xcode and also because it uses Swift result builders to set up interfaces.<\/p>\n\n<p>I think part of the reason people like SwiftUI is that it has so many batteries included. A longtime weakness of Cocoa is that it doesn&rsquo;t offer much in the way of reusable controllers or make it easy to set up interfaces in code (though that has improved somewhat). Imagine if Apple had continued iterating on <code>NSController<\/code> and made a Swift DSL for views and auto-layout. I think that could have been pretty great, and it would have been built atop a mature foundation, which you could drop down to if needed.<\/p>\n\n<p>Apple went a different way. But this is <a href=\"https:\/\/twitter.com\/frankreiff\/status\/1546891331301154817\">not<\/a> something only Apple can do. You can make the API\/DSL that you want on top of AppKit or UIKit and then write your apps to that. You may not be able to use SwiftUI today, but you can use it as inspiration and evolve your code in that direction.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/06\/17\/thoughts-on-swiftui-after-wwdc-2022\/\">Thoughts on SwiftUI After WWDC 2022<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2017\/05\/01\/life-without-interface-builder\/\">Life Without Interface Builder<\/a><\/li>\n<\/ul>\n\n<p id=\"interfacebuilder-swift-update-2022-10-07\">Update (2022-10-07): <a href=\"https:\/\/twitter.com\/stroughtonsmith\/status\/1574506931518988288\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/stroughtonsmith\/status\/1574506931518988288\">\n<p>Playing with Swift Result Builders to make SwiftUI-style UIKit layout. No autolayout, no Interface Builder (and no SwiftUI). So much of what&rsquo;s good about SwiftUI could have been done without the magic, the unreliability, or the upheaval.<\/p>\n<\/blockquote>\n\n<p id=\"interfacebuilder-swift-update-2024-02-27\">Update (2024-02-27): <a href=\"https:\/\/github.com\/michelf\/MFXUI\">Michel Fortin<\/a>:<\/p>\n<blockquote cite=\"https:\/\/github.com\/michelf\/MFXUI\">\n<p>MFXUI is a collection of helpers to build user interfaces for macOS, iOS, and tvOS using in a declartive style similar to SwiftUI. It builds hierarchies of AppKit or UIKit views and has some provisions for bindings. In the most cases, MFXUI uses the system views unchanged, only adding extension methods and initializers (many of which are provided by UXKit).<\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Maximilian Mackh (tweet): InterfaceBuilder.swift lets you quickly build complex UIKit layout in code, speed up native app development and is completely open source. [&#8230;] The SwiftUI approach to layout in code is objectively fantastic and has inspired many aspects of this library. On the flip side, actual SwiftUI layout behaviour is very similar to self-sizing [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2022-07-13T19:51:55Z","apple_news_api_id":"920e74aa-801b-497c-a23f-112e900c94aa","apple_news_api_modified_at":"2024-02-27T15:41:52Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAw==","apple_news_api_share_url":"https:\/\/apple.news\/Akg50qoAbSXyiPxEukAyUqg","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[200,69,370,31,2078,30,2385,74,71,901,1812],"class_list":["post-36502","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-autolayout","tag-cocoa","tag-interfacebuilder","tag-ios","tag-ios-15","tag-mac","tag-macos-14-sonoma","tag-opensource","tag-programming","tag-swift-programming-language","tag-swiftui"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/36502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=36502"}],"version-history":[{"count":5,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/36502\/revisions"}],"predecessor-version":[{"id":42243,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/36502\/revisions\/42243"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=36502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=36502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=36502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}