Adding Custom Views to the Library in Xcode 12

栏目: IT技术 · 发布时间: 3年前

内容简介:This question has split the Apple developer community for years. Could this year’s WWDC finally mark the end of that?Last year, Apple made a huge step forward in UI development with the introduction ofThis made it possible for a developer who prefers the v
Adding Custom Views to the Library in Xcode 12
What do you prefer: creating user interfaces visually or in code?

This question has split the Apple developer community for years. Could this year’s WWDC finally mark the end of that?

Last year, Apple made a huge step forward in UI development with the introduction of SwiftUI : For the first time, the visual approach and the coding approach spoke the same language. It doesn’t matter if you add a button in code or by dragging it to the design canvas – both representations are always in sync.

This made it possible for a developer who prefers the visual approach and another one who prefers the code approach to work on the same project without any conflict. Yet, one important thing was still missing: The ability to simply drag and drop your own views onto the canvas.

With WWDC 2020 , Apple has closed this gap – the feature is finally here! So let’s dive right in and see how to add your custom views in SwiftUI to the Xcode library!

Here’s our sample project that we’re going to refer to:

MyAwesomeCustomViews Download

Step 1: Create Custom Views in SwiftUI

In order to add custom views to the library, we first need a project. In this example, we’re going to create a simple app showcasing all our team members in a neat list.

Adding Custom Views to the Library in Xcode 12

We start with creating a new custom view called Row which we will later use for displaying an indiviual team member. It consists of a profile image, a title (for the team member’s name) and a subtitle (for the job description).

struct Row: View {
    var title: String
    var subtitle: String
    var image: Image

    var body: some View {
        HStack(spacing: 8) {
            image
                .resizable()
                .frame(width: 75, height: 75, alignment: .center)
            VStack(alignment: .leading, spacing: 4) {
                Text(title)
                Text(subtitle)
                    .opacity(0.5)
            }
            .font(.headline)
            Spacer()
        }
        .padding(8)
    }
}

This view simply adds several (sub)views and lays them out the way we want. But what’s still missing is the “card look”: the rounded rectangle frame around it and the subtle shadow.

To keep our Row view highly reusable and customizable, we don’t add the code for that to the view itself. Instead, we create a view modifier .card() for that which we can apply not only to a row, but to other views as well.

struct Card: ViewModifier {
    let cornerRadius: CGFloat

    func body(content: Content) -> some View {
        content
            .background(Color(.systemBackground))
            .cornerRadius(cornerRadius)
            .shadow(color: Color.primary.opacity(0.2), radius: 4)
    }
}

extension View {
    func card(cornerRadius: CGFloat = 8) -> some View {
        modifier(Card(cornerRadius: cornerRadius))
    }
}

With these components, we can now build a TeamMemberCell view, which combines the two things together:

struct TeamMemberCell: View {
    let teamMember: TeamMember

    var body: some View {
        Row(title: teamMember.name, subtitle: teamMember.position, image: teamMember.image)
            .card(cornerRadius: 8)
    }
}

Finally, we create a TeamList which creates a TeamMemberCell for each of our team members and arranges them in a vertical, scrollable stack. You can see how we did that in our sample project . We’ll skip that part in this article.

Step 2: Add Items to the Xcode View Library

All we’ve done so far isn’t new and could be accomplished with Xcode 11 as well. Now comes the cool part: Instead of composing the TeamMemberCell in code, we want to be able to assemble it with drag & drop in the design canvas. Before we can do that, we first need to let Xcode know about the custom views and modifiers we want to add to the view library.

For that, the new API LibraryContentProvider was introduced in Xcode 12. The following example adds the Row view and the .card() modifier to the library, alongside another custom view AppButton and a custom .loading modifier. (Feel free to check out the code for the latter two in our sample project .)

struct ViewProvider: LibraryContentProvider {

    @LibraryContentBuilder var views: [LibraryItem] {
        LibraryItem(Row(title: "", subtitle: "", image: Image("")))
        LibraryItem(AppButton(Text(""), action: {}))
    }

    func modifiers<V: View>(base: V) -> [LibraryItem] {
        [
            LibraryItem(base.card(cornerRadius: 8)),
            LibraryItem(base.loading(false))
        ]
    }

}

As you can see, we need to make a type conform to the LibraryContentProvider protocol to add new items to the Xcode library. However, we can’t just make our views and modifiers conform to that protocol (which we first assumed). Instead, we need to create a separate structure (which we called ViewProvider ) that implements this protocol. In its view property, we return all our custom views that we want to add to the library, wrapped in a LibraryItem . Similarly, we return all view modifiers that we want to have in the library from the modifiers function.

Note:For the views property, we use the LibraryContentBuilder function builder similar to how ViewBuilder can be used to add multiple views as children of a VStack , HStack or ZStack . That’s why there are no array brackets around the library items.

In our ViewBuilder example, we chose the easiest way to create each LibraryItem by using the initializer with only a single parameter. That works, but we can also customize how that library item appears in Xcode by providing more context. Let’s take a closer look at the LibraryItem initializer :

LibraryItem(
    Row(title: "", subtitle: "", image: Image("")), // the code to create the view
    visible: true,                                  // whether it's visible in the Xcode library
    title: "My Awesome Team Member Row",            // the custom name shown in the library
    category: .control,                             // a category to find you custom views faster
    matchingSignature: ""                           // the signature for code completion
)

First of all, we can define what code snippet should be added to the SwiftUI code when using the LibraryItem . We can further specify whether the item should only be visible for code completion or also appear when using the design canvas. Since the default value for the visible attribute is true , we usually omit this parameter. It is also possible to define a custom title, as well as a category (including .effect , .layout , .control and the default .other ). The category will be used for sorting the views and modifiers and also change their color in the Xcode library. A matching signature can also be added to determine which shortcut should trigger the code completion for the given modifier or view.

Step 3: Compose Views with Xcode 12

After building the project once, Row , AppButton , .card and .loading are available in the Xcode library, alongside all the native views! We can now use them to visually compose our TeamMemberCell .

Adding Custom Views to the Library in Xcode 12

With the design canvas open, you can add any of our custom views and modifiers to it by clicking the [+] button and simply dragging the respective item over to the canvas.

Adding Custom Views to the Library in Xcode 12

Ain’t that cool?! :sunglasses:

Adding Custom Views to the Library in Xcode 12

Note: We noticed that the library items sometimes don’t show up in the Xcode library immediately. This is probably because Xcode 12 is still in Beta and will hopefully be resolved soon. If it doesn’t work for you right from the beginning, don’t give up! Quit and reopen Xcode, clean, build, change a little bit of code – and we promise it’ll work eventually. :wink:

Conclusion

By providing the same tooling for custom views and modifiers as provided for native components in addition to many other changes to the whole toolchain, SwiftUI finally feels like a first-class citizen when it comes to UI development on iOS. It was a long way to go, but in the year 2020, visual user interface development with Xcode is feature-equivalent to creating SwiftUI views in code.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The NSHipster Fake Book (Objective-C)

The NSHipster Fake Book (Objective-C)

Mattt Thompson / NSHipster Portland, Oregon / 2014 / USD 19.00

Fake Books are an indispensable tool for jazz musicians. They contain the melody, rhythm, and chord changes for hundreds of standards, allowing a player to jump into any session cold, and "fake it" th......一起来看看 《The NSHipster Fake Book (Objective-C)》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具