- 新建 PostCell
import SwiftUI
struct PostCell: View {
let post : Post
var body: some View {
VStack{
HStack(spacing: 5){
Image(uiImage: UIImage(named:post.avatar)!)
.resizable() // 可缩放
.scaledToFill() // 等比填充
.frame(width:50,height: 50)
.clipShape(Circle()) // 裁剪为圆形图片
.overlay(
PostVIPBadge(vip :post.vip)
.offset(x: 16, y: 16) //偏移 调整位置
)
//alignment:.leading 左对齐
//spacing 俩个空间之间的距离
VStack(alignment:.leading,spacing: 5){
Text(post.name)
.font(Font.system(size:16))
.foregroundColor(Color.orange)
.lineLimit(1)
Text(post.date)
.font(Font.system(size:11))
.foregroundColor(Color.gray)
.lineLimit(1)
}.padding(.leading,10)
Spacer() // 填充控件之间的全部空隙
//判断达到条件 隐藏控件 如果没有关注则绘制显示
if !post.isFollowed{
Button(action: {
print("点击了关注")
}){
Text("关注")
.font(Font.system(size:14))
.foregroundColor(Color.orange)
.frame(width:50,height:26)
.overlay(RoundedRectangle(cornerRadius: 13)
.stroke(Color.orange,lineWidth: 1))
}.buttonStyle(BorderlessButtonStyle()) // 去除item的 按钮抢占点击事件。
}
}
Text(post.text).font(.system(size: 17))
if !post.images.isEmpty{
loadImage(name:post.images[0])
.resizable() //可缩放
.scaledToFill()
.frame(width:UIScreen.main.bounds.width-30,height: (UIScreen.main.bounds.width-30)*0.75)
.clipped()
}
Divider() // 添加分割线
HStack(spacing: 0){
Spacer()
PostCellToolBarButtom(image: "message", text: post.commentCountText, color: .black){
print("Click comment button")
}
Spacer()
PostCellToolBarButtom(image: "heart", text: post.likeCountText, color: .black){
print("Click comment ,message")
}
Spacer()
}
Rectangle() // 自定义填充分割线
.padding(.horizontal,-15)
.frame(height:10)
.foregroundColor(Color(red:238/255,green:238/255,blue :238/255))
}.padding(.horizontal,15)
.padding(.top,15)
}
}
struct PostCell_Previews: PreviewProvider {
static var previews: some View {
PostCell(post :postList.list[2])
}
}
- 模型类
import SwiftUI
struct PostList:Codable {
var list : [Post]
}
// 模型类
// let 声明常量。var 声明变量
//Identifiable 列表默认将id 作为唯一标识符
struct Post :Codable,Identifiable{
let id: Int
let avatar :String
let vip: Bool
let name:String
let date:String
var isFollowed : Bool
let text :String
let images :[String]
var commentCount:Int
var likeCount:Int
var isLiked:Bool
}
//extension 扩展某个类
extension Post{
//只读属性 不能赋值
var commentCountText:String{
if commentCount <= 0 {return "评论"}
if commentCount < 1000 {return "\(commentCount)"}
return String(format: "%.1fk", Double(commentCount)/1000)
}
var likeCountText:String{
if likeCount <= 0 {return "点赞"}
if likeCount < 1000 {return "\(likeCount)"}
return String(format: "%.1fk", Double(likeCount)/1000)
}
}
let postList = loadPostListData("PostListData_recommend_1.json")
func loadPostListData(_ fileName: String)-> PostList{
guard let url = Bundle.main.url(forResource: fileName, withExtension: nil) else{
fatalError("Can not find \(fileName) in main bundle")
}
guard let data = try? Data(contentsOf: url) else{
fatalError("Can not find \(url)")
}
guard let list = try? JSONDecoder().decode(PostList.self, from: data) else{
fatalError("Can not parse post list json data")
}
return list
}
func loadImage(name :String) -> Image{
return Image(uiImage: UIImage(named: name)!)
}
- 封装的 PostCellToolBarButtom 点赞 Buttom
import SwiftUI
struct PostCellToolBarButtom: View {
let image :String
let text :String
let color :Color
let action : () ->Void // 闭包 类似于 function 可以有参数 ,有则写在括号中
var body: some View {
Button(action:action){
HStack(spacing: 5){
Image(systemName: image)
.resizable()
.scaledToFit()
.frame(width:18,height: 18)
}
Text(text).font(.system(size: 15))
}.foregroundColor(color)
.buttonStyle(BorderlessButtonStyle())
}
}
struct PostCellToolBarButtom_Previews: PreviewProvider {
static var previews: some View {
PostCellToolBarButtom(image: "heart", text: "点赞", color: Color.red, action: {
print("点赞成功")
})
}
}
- 封装的角标 VIP
import SwiftUI
struct PostVIPBadge: View {
let vip : Bool
var body: some View {
Group{
if vip{
Text("V")
.bold() // 加粗
.font(.system(size: 11))
.frame(width:15,height: 15)
.foregroundColor(.yellow)
.background(Color.red)
.clipShape(Circle())
.overlay(RoundedRectangle(cornerRadius: 7.5).stroke(Color.white,lineWidth: 1))
}
}
}
}
struct PostVIPBadge_Previews: PreviewProvider {
static var previews: some View {
PostVIPBadge(vip :true)
}
}
- 最后实现 List
import SwiftUI
struct PostListView: View {
init(){
// 去除UITableView 默认的 分割线
UITableView.appearance().separatorStyle = .none
// 去除UITableViewCell 默认选中样式
UITableViewCell.appearance().selectionStyle = .none
}
var body: some View {
List{
//ForEach(postList.list,id: \.id){post in。
//因为在模型类中写了Identifiable 这里可以将 id 省略
ForEach(postList.list){post in
PostCell(post: post)
//去除 列表样式不正常 ,如不正常边距
.listRowInsets(EdgeInsets())
}
}
}
}
struct PostListView_Previews: PreviewProvider {
static var previews: some View {
PostListView()
}
}
效果就是下面这个样子
3.gif
总结:
- 点击Cell 多个Buttom 响应
解决方式: 给每个Buttom 设置 .buttonStyle(BorderlessButtonStyle())
- UITabview 默认的分割线
解决方式:
init(){
// 去除UITableView 默认的 分割线
UITableView.appearance().separatorStyle = .none
// 去除UITableViewCell 默认选中样式
UITableViewCell.appearance().selectionStyle = .none
}
- 和Android RecyclerView 的区别
- 不需要写适配器
- IOS List 只需要给它提供一个唯一标识符
网友评论