zoukankan      html  css  js  c++  java
  • IOS小组件(3):SwiftUI开发小组件布局入门

    引言

      经过上一篇文章,我们已经可以在桌面上展示出一个小组件出来了,你肯定想小试牛刀,动手改一改,那我们就从改小组件的布局做起吧。本文不会讲解Swift语法,如果是熟悉Flutter,Kotlin这种语言的,问题也不大。本文只讲解小组件中常用的SwiftUI组件。

    本文大纲

    • 小组件布局怎么区分组件型号:大中小
    • 常用基础组件 Text Image
    • 常用容器组件 ZStack VStack HStack
    • 常用属性:充满父布局 文字内部居中 等分剩余空间(Spacer)

    小组件布局怎么区分组件型号:大中小

    struct Widget1EntryView : View {
        // 这句代码能从上下文环境中取到小组件的型号
        @Environment(.widgetFamily) var family
        
        // 组件数据
        var entry: Provider.Entry
    
        // 这个 body 中就是自己需要实现的组件布局
        var body: some View {
            switch family {
            case .systemSmall:  // 小号
                Text(entry.date, style: .time)
            case .systemMedium: // 中号
                Text(entry.date, style: .time)
            case .systemLarge:  // 大号
                Text(entry.date, style: .time)
            @unknown default:
                Text(entry.date, style: .time)
            }
        }
    }
    

    常用基础组件Text使用

    Text("普通文本")
        .font(.system(size: 15))    // 字体
        .foregroundColor(Color(hexString: "#FF0000"))
    // Text以日期作为参数时可以有以下多种使用方式,参考官网定义
    // 重要:其中的.timer比较有用,可以用来做时钟的刷新
    /// A predefined style used to display a `Date`.
    public struct DateStyle {
    
        /// A style displaying only the time component for a date.
        ///
        ///     Text(event.startDate, style: .time)
        ///
        /// Example output:
        ///     11:23PM
        public static let time: Text.DateStyle
    
        /// A style displaying a date.
        ///
        ///     Text(event.startDate, style: .date)
        ///
        /// Example output:
        ///     June 3, 2019
        public static let date: Text.DateStyle
    
        /// A style displaying a date as relative to now.
        ///
        ///     Text(event.startDate, style: .relative)
        ///
        /// Example output:
        ///     2 hours, 23 minutes
        ///     1 year, 1 month
        public static let relative: Text.DateStyle
    
        /// A style displaying a date as offset from now.
        ///
        ///     Text(event.startDate, style: .offset)
        ///
        /// Example output:
        ///     +2 hours
        ///     -3 months
        public static let offset: Text.DateStyle
    
        /// A style displaying a date as timer counting from now.
        ///
        ///     Text(event.startDate, style: .timer)
        ///
        /// Example output:
        ///    2:32
        ///    36:59:01
        public static let timer: Text.DateStyle
    }
    

    IOS中的颜色RGB不是安卓的0-255,而是0-1,这里写了一个拓展函数支持十六进制颜色字符串

    #if (arch(arm64) || arch(x86_64))
    
    import Foundation
    import SwiftUI
    
    @available(iOS 13.0, *)
    extension Color {
        
        //#ARGB
        init?(hexString: String) {
            var hex = hexString;
            guard hexString.starts(with: "#") else {
                return nil
            }
            hex.remove(at: hexString.startIndex)
            var value: UInt64 = 0
            Scanner(string: hex).scanHexInt64(&value)
    
            var a = 0xFF / 255.0
            if hex.count > 7 {
                a = Double(value >> 24) / 255.0
            }
            let r = Double((value & 0xFF0000) >> 16) / 255.0;
            let g = Double((value & 0xFF00) >> 8) / 255.0;
            let b = Double(value & 0xFF) / 255.0
            self.init(red: Double(r), green: Double(g), blue: Double(b))
            _ = self.opacity(Double(a))
        }
    }
    

    常用基础组件Image使用

    // 访问bundle中的资源
    Image("imageName")
    // 通过UIImage加载文件夹中的图片资源
    Image(uiImage: UIImage(contentsOfFile: "picPath") ?? UIImage())
        .resizable()
        .scaledToFill()
        .clipped()
        .colorMultiply(Color(hexString: config.textColor) ?? Color.white) // 重要:这个类似安卓中的colorFilter可以修改图片颜色
        .frame( 36, height: 36, alignment: .center)
    

    常用容器组件ZStack使用,类似安卓里面的FrameLayout,可以重叠布局

    ZStack {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .time)
    }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
    .background(Color(hexString: "#00FFFF"))
    

    常用容器组件HStack使用,水平方向布局

    HStack {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .time)
    }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
    .background(Color(hexString: "#00FFFF"))
    

    常用容器组件VStack使用,垂直方向布局

    VStack {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .time)
    }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
    .background(Color(hexString: "#00FFFF"))
    

    充满父布局怎么实现

    .frame(maxWidth: .infinity, maxHeight: .infinity)
    VStack {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .time)
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)	// 充满父布局
    .background(Color(hexString: "#00FFFF"))
    

    文字内部居中(multilineTextAlignment)

    .multilineTextAlignment(.center)
    VStack {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .timer)
            .multilineTextAlignment(.center)		// 让文字在Text内部居中
            .background(Color(hexString: "#FFFF00"))
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color(hexString: "#00FFFF"))
    

    等分剩余空间(Spacer)

    VStack {
        Spacer()
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Spacer()
        Text(entry.date, style: .timer)
            .multilineTextAlignment(.center)
            .background(Color(hexString: "#FFFF00"))
        Spacer()
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color(hexString: "#00FFFF"))
    

    控制间距(spacing)

    VStack(spacing: 10) {
        Text("普通文本")
            .font(.system(size: 15))    // 字体
            .foregroundColor(Color(hexString: "#FF0000"))
        Text(entry.date, style: .timer)
            .multilineTextAlignment(.center)
            .background(Color(hexString: "#FFFF00"))
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color(hexString: "#00FFFF"))
    

    结语

      关于小组件SwiftUI布局就讲这么多,入个门差不多了,另外,小组件并不能使用全部的SwiftUI控件,只能使用一些基本的控件,更多详情可以查看官网 https://developer.apple.com/documentation/widgetkit/swiftui-views

  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/popfisher/p/14736526.html
Copyright © 2011-2022 走看看