• 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

  • 相关阅读:
    2015 9月15日 工作计划与执行
    2015 9月14日 工作计划与执行
    2015 9月14日 周计划
    2015 9月11日 工作计划与执行
    2015 9月10日 工作计划与执行
    2015 9月9日 工作计划与执行
    2015 9月8日 工作计划与执行
    js 有用信息集
    2015 9月7日 工作计划与执行
    文件间的编译依存关系 分类: C/C++ 2015-06-10 15:37 34人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/popfisher/p/14736526.html
Copyright © 2020-2023  润新知