引言

  经过上一篇文章,我们已经可以在桌面上展示出一个小组件出来了,你肯定想小试牛刀,动手改一改,那我们就从改小组件的布局做起吧。本文不会讲解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(width: 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

IOS Widget(3):SwiftUI开发小组件布局入门的更多相关文章

  1. Android Widget小组件开发(一)——Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的!

    Android Widget小组件开发(一)--Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的! PS:学习自某网站(不打广告) 这个小组件相信大家都很熟悉吧,以前的墨迹天气 ...

  2. Android开发工程师文集-1 小时学会Widget小组件开发

    前言 大家好,给大家带来Android开发工程师文集-1 小时学会Widget小组件开发的概述,希望你们喜欢 学会用Widget (小组件) Widget小组件很方便,很快捷,可以个性化,自己定制,相 ...

  3. IOS Widget(1):概述

    引言   本系列文章作者是安卓开发,以安卓开发的视角学习IOS小组件,记录一下踩坑记录,如有讲得不对的地方,路过大佬多包涵.如果你是想深入学习小组件,建议您顺着笔者的编号顺序阅读本系列文章.如果曾经了 ...

  4. IOS Widget(4-1):创建可配置小组件(静态配置数据)

    引言   经过前面几篇文章阅读,已经掌握开发一款小组件的基本技能了,接下来开始掌握一些相对高级一点的技能.本文创建一个可配置小组件,通过修改时间类型,让Text空间显示不同格式的时间. 本文大纲 添加 ...

  5. IOS Widget(5):小组件刷新机制

    引言   前面的章节学完已经让我们可以顺利实现一个小组件了,但是小组件里面的数据如何刷新的呢,本节内容将讲解IOS的刷新机制. 大纲 系统如何管理小组件刷新 Timeline刷新机制 Timeline ...

  6. IOS小组件(8):App与Widget数据共享

    引言   Widget是一个迷你版的App,IOS有沙盒机制,不同App之间无法直接共享数据.组件和主App之间其实就是不同App的关系,所以也无法通过userdefaults.standard来传数 ...

  7. iOS开发之组件化架构漫谈

    前段时间公司项目打算重构,准确来说应该是按之前的产品逻辑重写一个项目.在重构项目之前涉及到架构选型的问题,我和组里小伙伴一起研究了一下组件化架构,打算将项目重构为组件化架构.当然不是直接拿来照搬,还是 ...

  8. Widget小组件

    一.使用步骤: 1.建立Widget的样式布局文件widght,布局只支持几种,比如,相对布局,线性布局,帧布局,布局里支持的控件也是有限的. 2.在res下建立一个新的文件夹我的命名为xml 3.在 ...

  9. 写给 Android 开发的小程序布局指南,Flex 布局!

    一.序 Hi,大家好,我是承香墨影! 最近在做小程序,验证一些方向,开发效率确实很快,就是各种微信的审核有点费劲,但是总归是有办法解决的. 想要开发一款小程序,其实和我们正常写一款 App 类似,你需 ...

随机推荐

  1. HDOJ-1213(简单并查集)

    How many tables HDOJ-1213 #include<iostream> #include<cstring> #include<cstdio> #i ...

  2. 任务队列 与 Celery概述

    一.任务队列(Task Queues) 1.1 什么是任务队列? 任务队列用于管理后台工作,通常这些后台工作必须在 HTTP请求-响应循环 之外执行. 1.2 为什么需要任务队列? 对于那些不是由客户 ...

  3. 在C++中实现aligned_malloc

    malloc的默认行为 大家都知道C++中可以直接调用malloc请求内存被返回分配成功的内存指针,该指针指向的地址就是分配得到的内存的起始地址.比如下面的代码 int main() { void * ...

  4. FreeBSD pkg安装软件时出现创建用户失败解决

    问题示例:[1/1] Installing package...===> Creating groups.Creating group 'package' with gid '000'.===& ...

  5. BIMFACE二次开发【C#系列】

    本系列文章主要介绍使用 C# .ASP.NET(MVC)技术对 BIMFACE 平台进行二次开发,以满足本公司针对建筑行业施工图审查系统的业务需求,例如图纸模型(PDF 文件.二维 CAD 模型.三维 ...

  6. YoloV3 记录

    常用于目标检测,因为最近要从目标分类问题转到目标检测中去. tensoflow.Keras(大公司一般都用这个).pytorch(本次学习)------------------主要框架 程序设计模块规 ...

  7. Win 10 下Pipenv源码安装 odoo12

    因为,本身电脑已经安装odoo8,9,10等odoo的版本,当时,没有考虑是直接是统一的环境很配置. 现在,在odoo11的环境下,需要Python 3的语言环境可以很好地支持odoo11的功能,所以 ...

  8. ECMAScript 2018(ES9)新特性简介

    目录 简介 异步遍历 Rest/Spread操作符和对象构建 Rest Spread 创建和拷贝对象 Spread和bject.assign() 的区别 正则表达式 promise.finally 模 ...

  9. Web 前端 - 又不仅限于 Web 前端 - 协程锁问题

    前言 最近两天的 web 前端开发中,早前的锁实现 (自旋锁) 出现了一些不合理的现象,所以有了这片随笔 什么是协程锁?能点进这个博客的的你肯定是明白的,不明白的人根本搜不到我这随笔,不多做赘述. 一 ...

  10. [矩阵乘法]裴波拉契数列II

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I [矩阵乘法]裴波拉契数列II [矩阵乘法]裴波拉契数列II Description 形如 1 1 2 3 5 8 13 21 34 55 89 ...