Optimizing views in SwiftUI using EquatableView

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

内容简介:I have good news for you.As you remember, we already talked about diffing in

SwiftUI provides us a very fast and easy to use diffing algorithm, but as you might know, diffing is a linear operation. It means that diffing will be very fast for simple layouts and can take some time for a complicated layout.

I have good news for you. SwiftUI allows us to replace the standalone diffing algorithm with our custom logic. This week we will talk about optimizing our SwiftUI layouts using the equatable modifier.

Diffing in SwiftUI

As you remember, we already talked about diffing in SwiftUI , but let me remind how it works. Whenever you change the source of truth for your views like @State or @ObservableObject , SwiftUI runs body property of your view to generate a new one. As the last step, SwiftUI renders a new view if something changed. The process of calculating a new body depends on how deep is your view hierarchy. Happily, we can replace SwiftUI diffing with our simplified version whenever we know the better way to determine changes.

To learn more about diffing, take a look at “You have to change mindset to use SwiftUI” post .

EquatableView

Sometimes we don’t need the true diffing of SwiftUI , or we want to ignore some changes in data, and this is the exact place where we can use the EquatableView struct. EquatableView struct is a wrapper for a View , and it also conforms to View protocol. All you need to do to use EquatableView is conforming your view to Equatable protocol. Let’s take a simple look at a good example.

struct CalendarView: View, Equatable {
    let sleeps: [Date: [Sleep]]
    let dates: [Date]

    var body: some View {
        List {
            ForEach(dates, id: \.self) { date in
                Section(header: Text("\(date, formatter: DateFormatter.mediumDate)")) {
                    ForEach(self.sleeps[date, default: []], id: \.id) { sleep in
                        CalendarRow(sleep: sleep)
                    }
                }
            }
        }.listStyle(GroupedListStyle())
    }
}

In the example above, you see the code from my NapBot app. It is a calendar view that represents your sleep per day. I decide to replace SwiftUI diffing with my own by adding Equatable conformance. As you can see, it is a straightforward process. You can go further by overriding == function and adding your custom logic there.

struct CalendarView: View, Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.sleeps.count == rhs.sleeps.count
    }
}

Now we can wrap our CalendarView with EquatableView .

Remember, you have to wrap your view with EquatableView to replace standalone diffing with yours.

struct CalendarContainerView: View {
    @EnvironmentObject var store: CalendarStore

    var body: some View {
        EquatableView(
            CalendarView(
                sleeps: store.sleeps,
                dates: store.dates
            )
        ).onAppear(perform: store.fetch)
    }
}

equatable modifier

SwiftUI allows us to avoid wrapping with EquatableView by using an equatable modifier. Basically, it does the same thing but in a short way.

struct CalendarContainerView: View {
    @EnvironmentObject var store: CalendarStore

    var body: some View {
        CalendarView(sleeps: store.sleeps, dates: store.dates)
            .equatable()
            .onAppear(perform: store.fetch)
    }
}

Container views and equatable rendering views

It is so easy to add Equatable conformance to your view when it only renders some data. You even don’t need to override == function . You can quickly achieve this behavior by extracting your views into Container and Rendering views. We already talked multiple times on my blog about Container and Rendering views. Rendering views simply take some data and render it. That’s it.

Rendering views should not contain any logic or state manipulations, and it should delegate them to Container views. This separation allows you to make your Rendering views conforming Equatable in an effortless way.

To learn more about Container and Rendering views , take a look at my “Introducing Container views in SwiftUI” post .

Conclusion

SwiftUI allows us to build our apps in a very new way, where the framework itself applies a lot of magic behind the scene. But I’m delighted that SwiftUI provides so many capabilities to customize default behavior. I hope you enjoy the post. Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading, and see you next week!


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

查看所有标签

猜你喜欢:

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

鲜活的数据

鲜活的数据

[美] Nathan Yau / 向怡宁 / 人民邮电出版社 / 2012-10-1 / 69.00元

在生活中,数据几乎无处不在,任我们取用。然而,同样的数据给人的感觉可能会千差万别:或冰冷枯燥,让人望而生畏、百思不解其意;或生动有趣,让人一目了然、豁然开朗。为了达到后一种效果,我们需要采用一种特别的方式来展示数据,来解释、分析和应用它。这就是数据可视化技术。Nath an Yau是这一创新领域的先锋。在本书中,他根据数据可视化的工作流程,先后介绍了如何获取数据,将数据格式化,用可视化工具(如R)......一起来看看 《鲜活的数据》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具