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

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

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

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

swift 复制代码
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))
        }
    }
}

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

swift 复制代码
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)
    }
}

提炼代码封装

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

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

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

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

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

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

swift 复制代码
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 设置为只读的属性,返回我们对应的试图。

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

swift 复制代码
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 会有点手足无措。

swift 复制代码
struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            ServerSelectMenuView()
            Spacer()
        }
    }
}

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

swift 复制代码
struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            Spacer()
                .frame(height:150)
            ServerSelectMenuView()
            Spacer()
        }
    }
}

使用 Padding 添加间距

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

swift 复制代码
struct LoginPage: View {
    var body: some View {
        VStack {
            Spacer()
                .frame(height:100)
            Image("winner_logo")
            Spacer()
                .frame(height:150)
            ServerSelectMenuView()
                .padding()
            Spacer()
        }
    }
}

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

swift 复制代码
ServerSelectMenuView()
    .padding(EdgeInsets(top: 0, leading: 45, bottom: 0, trailing: 45))

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

swift 复制代码
ServerSelectMenuView()
    .padding(.leading,45)
    .padding(.trailing,45)

效果都是一样的。

相关推荐
东坡肘子2 天前
Swift 并发正被更广泛地接纳 -- 肘子的 Swift 周报 #133
人工智能·swiftui·swift
文件夹__iOS4 天前
SwiftUI 核心选型:class + ObservableObject VS struct + @State
ios·swiftui·swift
Wenzar_6 天前
# 发散创新:SwiftUI 中状态管理的深度实践与重构艺术 在 SwiftUI 的世界里,**状态驱动 UI 是核心哲学**。但随
java·python·ui·重构·swiftui
大熊猫侯佩7 天前
GeometryReader 生存指南(下集):与恶魔共舞——陷阱、禁忌与最终救赎
swiftui·performance·layout·frame·stack·geometryreader·preferencekey
大熊猫侯佩7 天前
别被系统绑架:SwiftUI List 替换背后的底层逻辑
swiftui·swift·apple
东坡肘子9 天前
从 OpenSwiftUI 到 DanceUI:换个方式 Dive SwiftUI -- 肘子的 Swift 周报 #132
人工智能·swiftui·swift
用户79457223954139 天前
【SwiftyJSON】拯救你的 as? [String: Any]——链式 JSON 访问的正确姿势
swiftui·objective-c·swift
用户79457223954139 天前
【Moya】为什么你的 Alamofire 代码需要再封装一层?
swiftui·objective-c·swift
空中海10 天前
第二章:SwiftUI 视图基础
ios·swiftui·swift