第七章 组件提炼|代码清爽|Padding

0 阅读3分钟

我们对于 LoginValueContentView 的 组件已经布局完毕,接下来就需要我们进行提炼,做成可以复用的组件。

我们组件分成三个部分,分别是leftcenterright.

我们新增三个变量将组件代码改造如下

struct LoginValueContentView<L:View,C:View,R:View>: View {
    let left:L
    let center:C
    let right:R
    @EnvironmentObject private var appColor:AppColor
    var body: some View {
        VStack(spacing: 8.0) {
            HStack(spacing: 15) {
                left
                center
                right
            }
            Rectangle()
                .frame(height:0.5)
                .foregroundColor(Color(uiColor: appColor.c_cccccc))
        }
    }
}

这样我们的组件变得结构变得十分的复杂,我们将预览的初始化更改为

struct LoginValueContentView_Previews: PreviewProvider {
    @StateObject static var appColor:AppColor = AppColor()
    static var previews: some View {
        LoginValueContentView(left:Image("server_icon"),
                              center:                 Text("请选择服务器")
                                .frame(maxWidth:.infinity,
                                       alignment: .leading)
                                .lineLimit(1)
                                .foregroundColor(Color(uiColor: appColor.c_cccccc)),
                              right: Image("drop_icon"))
            .previewLayout(.sizeThatFits)
            .environmentObject(appColor)
    }
}

image-20211116172716543

提炼代码封装

我们使用最新组件的效果已经和我们刚才的想过一模一样。

所以我们对于 SwiftUI 视图的提炼,不能上来就盲目的封装,需要先实现效果,再进行提炼。

我们已经对于 LoginValueContentView 视图封装的完毕,接下来我们就分别来做我们选取服务器,输入用户名和输入密码组件。

我们在View文件夹,新建一个 ServerSelectMenuView.swift,用于显示选择服务器选择的试图。

我们将刚才封装预览的代码复制进来即可。

别忘记在在预览设置 Environment Object, 所有需要 Environment Object 都需要我们在预览哪里进行设置,的确有点不方便。

struct ServerSelectMenuView: View {
    @EnvironmentObject private var appColor:AppColor
    var body: some View {
        LoginValueContentView(left:Image("server_icon"),
                              center:                 Text("请选择服务器")
                                .frame(maxWidth:.infinity,
                                       alignment: .leading)
                                .lineLimit(1)
                                .foregroundColor(Color(uiColor: appColor.c_cccccc)),
                              right: Image("drop_icon"))
    }
}

虽然这个效果已经达到,但是我们的代码看起来十分的乱,因为都在一个属性里面。

为了能够让代码看起来更加的清爽,我们将 leftcenterright 设置为只读的属性,返回我们对应的试图。

重新构造代码如下,看起来确实清爽了很多。

struct ServerSelectMenuView: View {
    @EnvironmentObject private var appColor:AppColor
    var body: some View {
        LoginValueContentView(left: leftView,
                              center: centerView,
                              right: rightView)
    }
    
    private var leftView:some View {
        Image("server_icon")
    }
    
    private var centerView:some View {
        Text("请选择服务器")
          .frame(maxWidth:.infinity,
                 alignment: .leading)
          .lineLimit(1)
          .foregroundColor(Color(uiColor: appColor.c_cccccc))
    }
    
    private var rightView:some View {
        Image("drop_icon")
    }
}

我们将新增 ServerSelectMenuView 添加到我们的 LoginPage 页面。

别忘记添加 Environment Object!

别忘记添加 Environment Object!

别忘记添加 Environment Object!

重要的事情说三遍,对于我自己都经常忘记添加,如果你不知道使用的组件有 @Environment Object 会有点手足无措。

struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            ServerSelectMenuView()
            Spacer()
        }
    }
}
image-20211116175556698

为了让选择服务器控件和一点的距离,我们中间添加一点间距。

struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            Spacer()
                .frame(height:150)
            ServerSelectMenuView()
            Spacer()
        }
    }
}
image-20211116175955396

使用 Padding 添加间距

我们选择的组件竟然宽度铺满了,但是我们的设计图左右两侧是有间距的,这个时候我们可以设置 Padding

struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            Spacer()
                .frame(height:150)
            ServerSelectMenuView()
                .padding()
            Spacer()
        }
    }
}
image-20211116180720440

我们使用Padding,添加了一个默认的值间距。而且上下左右都有间距,其实我们只需要左右的间距,并且需要设置为设计稿45大小。

ServerSelectMenuView()
    .padding(EdgeInsets(top: 0, leading: 45, bottom: 0, trailing: 45))

其实我们还可以分开进行设置

ServerSelectMenuView()
    .padding(.leading,45)
    .padding(.trailing,45)

效果都是一样的。