-
Notifications
You must be signed in to change notification settings - Fork 207
demo和说明
我们先看看要完成的效果:
布局及元素构成很简单,那么接下来我们看如何通过 ArgoKit
来完成.
在开始布局之前我们可以回忆一下:
UIStackView
这个应该很熟悉,接下来的布局行为可以由 UIStackView
来联想就好理解了.
如果要把要做的效果图通过 UIStackView
来实现,我们大致应该这样做:
- 先定义一个垂直排列的 StackView
- 在垂直排列的
StackView
中定义三个水平排列的StackView
这样这个例子中的大致布局就完成了,如图:
同样在三个水平的 StackView 中我们分别命名为: Stack1,Stack2,Stack3
元素构成是
同理参考 1.1.1
同理参考 1.1.1
布局的思路有了,我们看如何使用 ArgoKit
来描述出 View
.
在开始之前我们需要了解:VStack
、HStack
我们可以把他暂时理解为:
VStack = (垂直方向的 UIStackView) HStack = (水平方向的 UIStackView)
但是她们又比 UIStackView
更强大一些, 我们称它们为弹性盒子.
关于弹性盒子 这个教程能快速让你掌握。
接下来我们正式开始
我们把布局的思路用代码实现。
代码是这样的:
var body: View {
VStack() {
/// 内容
}.padding(edge: .all, value: 15)
}
padding(edge: .all, value: 15)
是定义 VStack
距离上下左右 都是 15
var body: View {
VStack() {
HStack {
}.padding(edge: .bottom, value: 15)
HStack {
}
HStack {
}.padding(edge: .top, value: 15)
}.padding(edge: .all, value: 15)
}
var body: View {
VStack() {
HStack {
Text("<")
.padding(edge: .right, value: 5)
.alignSelf(.center)
Image("turtlerock")
.circle()
.width(35)
.height(35)
VStack {
HStack {
Text("MOMO 科技")
.font(style: .bold)
.padding(edge: .right, value: 5)
Text("Liv 6")
.textColor(.darkGray)
.textAlign(.center)
.size(width: 40, height: 16)
.font(size: 9)
.backgroundColor(.green)
}
Text("self.model.descriptionself.model.descriptionself.model.descriptionself.model.description")
.font(style: .bold)
.textColor(.gray)
}.padding(edge: .left, value: 5).shrink(1)
Spacer()
Button(text: ":") {
print("点击")
}.size(width: 35, height: 35)
}.alignItems(.center)
.padding(edge: .bottom, value: 15)
HStack {
}.height(.percent(67))
HStack {
}.padding(edge: .top, value: 15)
}.padding(edge: .all, value: 15)
}
1、 .alignSelf(.center)
这个是弹性盒子的属性:alignSelf
是针对盒子某一个元素的布局行为. 这里是 设置 center
居中。
关于弹性盒子 这里有详细的解释.
2、.circle()
这个是设置图片是一个圆
3、 .shrink(1)
主要处理视图内容拥挤的时候对视图收缩的占比关系,数值越大收缩的幅度越大. 默认是 0
, 这里只对它唯一设置1
就是最大值.
4、.alignItems(.center)
盒子内元素间的对齐和空间分配, 这里设置 居中 .center
这里面的内容是一个图片. 左右没有占据元素,点击图片应该是会有一个事件.
我们这里就是设置一个按钮,就不需要 HStack
包装了, 按钮的内容是一个图片。
用 ArgoKit
HStack
里面的内容是这样的:
Button {
print("放大图片事件")
} builder: { () -> View in
Image("turtlerock")
.cornerRadius(12)
.grow(1) /// .width(100%)
.alignSelf(.stretch) /// .height(100%)
}.height(.percent(67))
- 1、.cornerRadius(12)
设置图片圆角是 12
- 2、.grow(1)
指定了弹性盒子容器中剩余空间的分配关系,只分配设置的grow 值的视图。
比如:
size:当前盒子的宽度是: 200
, 高度是: 100
方向:水平排列
内容:盒子中有 view1
, view2
, view3
三个视图.分别占用宽度是 20,20,20
. 那么未占用的内容宽度有 140
.
当我们设置 view1
的 grow = 1
,其它不设置。那么未占用的宽度都会分配给 view1, 同理如果设置等宽那么设置 grow
的值相同 (>0 默认是0)
即可。
比例分配原则:
所有内容的:grow
值之和是总值,按各 view
的 grow
值的占用比例去分配剩下未占用的空间。
这里设置 .grow(1)
等效于 .width(100%)
- 3、.alignSelf(.stretch)
alignItems
是设置盒子内的元素统一的行为,而
alignSelf 是针对盒子某一个元素的布局行为。
这里是 stretch
等效于 .height(100%)
- 4、.height(.percent(67))
.percent(67)
是占用父视图高度的 67%
最后一个 HStack 里面的内容是 三个事件按钮,一个标签. 都是水平排列。 三个按钮左排列,标签是右排列。整体水平居中展示.
由于三个事件按钮都是一样的我们定义一个就可以了,对于事件我们使用一个枚举去区别。
事件这样定义:
enum Action {
case like
case praise
case share
}
事件的 UI 我们可以这样定义一个函数返回 View:
func button(_ text: String, _ action: Action) -> View {
return {
Button {
switch action {
case .like:
print("点赞")
case .praise:
print("夸")
case .share:
print("分享")
}
} builder: { () -> View in
Text(text)
}
}()
}
var like: ArgoKit.View {
HStack {
self.button("👍 赞", .like)
self.button("😄 夸", .praise)
.padding(edge: .left, value: 15)
self.button("🤘 分享", .praise)
.padding(edge: .left, value: 15)
}
}
var action: View {
HStack {
self.like
Spacer()
Text("特权操作")
.font(size: 10)
.textColor(.gray)
.alignSelf(.center)
}
}
Spacer()
是把两边的视图分到两边. self.like
靠左,Text("特权操作")
靠右
这样我们最后一个 HStack 的 View 就完成了。
接下来我们需要整体整理一下.
它是这样的:
var user: View {
HStack {
Text("<")
.padding(edge: .right, value: 5)
.alignSelf(.center)
Image(self.model.userImage)
.circle()
.width(35)
.height(35)
VStack {
HStack {
Text(self.model.name)
.font(style: .bold)
.padding(edge: .right, value: 5)
Text("Liv \(self.model.live)")
.textColor(.darkGray)
.textAlign(.center)
.size(width: 40, height: 16)
.font(size: 9)
.backgroundColor(.green)
}
Text("self.model.descriptionself.model.descriptionself.model.descriptionself.model.description")
.font(style: .bold)
.textColor(.gray)
}.padding(edge: .left, value: 5).shrink(1)
Spacer()
Button(text: ":") {
print("点击")
}.size(width: 35, height: 35)
}.alignItems(.center)
}
它是这样的:
var image: View {
Button {
print("放大图片事件")
} builder: { () -> View in
Image(self.model.image)
.clipsToBounds(true)
.cornerRadius(12)
.grow(1) /// .width(100%)
.alignSelf(.stretch) /// .height(100%)
}
}
第三个咱们已经拆成了 var action: View
直接用即可
var body: View {
VStack() {
self.user
.padding(edge: .bottom, value: 15)
self.image
.height(.percent(67))
self.action
.padding(edge: .top, value: 15)
.height(35)
}.padding(edge: .all, value: 15)
.alignItems(.stretch)
}
这样我们的这个 Demo 就完成了.
完整 Demo 源码在最后
ImagePage.swift 文件
import ArgoKit
class ImagePage: ArgoKit.View {
init(model: ImagePageModel) {
self.model = model
}
var model: ImagePageModel
var isRequest = true
typealias View = ArgoKit.View
var body: View {
VStack() {
self.user
.padding(edge: .bottom, value: 15)
self.image
.height(.percent(67))
self.action
.padding(edge: .top, value: 15)
.height(35)
}.padding(edge: .all, value: 15)
.alignItems(.stretch)
}
var user: View {
HStack {
Text("<")
.padding(edge: .right, value: 5)
.alignSelf(.center)
Image(self.model.userImage)
.circle()
.width(35)
.height(35)
VStack {
HStack {
Text(self.model.name)
.font(style: .bold)
.padding(edge: .right, value: 5)
Text("Liv \(self.model.live)")
.textColor(.darkGray)
.textAlign(.center)
.size(width: 40, height: 16)
.font(size: 9)
.backgroundColor(.green)
}
Text("self.model.descriptionself.model.descriptionself.model.descriptionself.model.description")
.font(style: .bold)
.textColor(.gray)
}.padding(edge: .left, value: 5).shrink(1)
Spacer()
Button(text: ":") {
print("点击")
}.size(width: 35, height: 35)
}.alignItems(.center)
}
var action: View {
HStack {
self.like
Spacer()
Text("特权操作")
.font(size: 10)
.textColor(.gray)
.alignSelf(.center)
}
}
var like: ArgoKit.View {
HStack {
self.button("👍 赞", .like)
self.button("😄 夸", .praise)
.padding(edge: .left, value: 15)
self.button("🤘 分享", .praise)
.padding(edge: .left, value: 15)
}
}
var image: View {
Button {
print("放大图片事件")
} builder: { () -> View in
Image(self.model.image)
.clipsToBounds(true)
.cornerRadius(12)
.grow(1) /// .width(100%)
.alignSelf(.stretch) /// .height(100%)
}
}
func button(_ text: String, _ action: Action) -> View {
return {
Button {
switch action {
case .like:
print("点赞")
case .praise:
print("夸")
case .share:
print("分享")
}
} builder: { () -> View in
Text(text)
}
}()
}
enum Action {
case like
case praise
case share
}
}
#if canImport(SwiftUI) && DEBUG
import ArgoKitPreview
import SwiftUI
@available(iOS 13.0.0, *)
struct ImagePage_Previews: PreviewProvider {
static var previews: some SwiftUI.View {
ArgoRender {
ImagePage(model: ImagePageModel()).body
}
}
}
#endif
ImagePageModel.swift 文件
import Foundation
import ArgoKit
struct ImagePageModel: ArgoKitIdentifiable, Codable, Identifiable {
var reuseIdentifier: String
let id: String
let userImage: String
let live: Int
var name: String
let description: String
let image: String
/// 伪数据
init() {
reuseIdentifier = "reuseIdentifier"
id = "idsdsd sd sd"
userImage = "turtlerock"
live = 6
name = "MOMO 科技"
description = "7 月23日 来自通讯录好友"
image = "turtlerock"
}
}