01- what's new in uikit

1,439 阅读4分钟

在2022年 Apple WWDC 开发者大会中, UIkit框架增加了一些新特性, 本文将介绍 UIkit相关的API.

1. UICalendarView iOS16 新增的日历控件

image.png image.png

- 初始化UICalendarView
  let calendarView = UICalendarView()
  calendarView.frame = CGRect.init(x: 0.0, y: 100.0, width: 375.0, height: 300.0)
  calendarView.delegate = self // 设置代理
  let gregorianCalendar = Calendar(identifier: .gregorian)
  calendarView.calendar = gregorianCalendar // 跟日历有关的属性 
  view.addSubview(calendarView)
- 单选的模式
let multiDateSection = UICalendarSelectionSingleDate(delegate: self)
multiDateSection.selectedDate = selectDate // 默认选择日期
calendarView.selectionBehavior = multiDateSection
- 多选模式
   let multiDateSection = UICalendarSelectionMultiDate(delegate: self)
   multiDateSection.selectedDates = [] // 默认选择多个日期
   calendarView.selectionBehavior = multiDateSection
- UICalendarViewDelegate 日历控件代理数据源

这里主要返回一个自定义视图, 显示在日历数字下边区域, 跟 UITableView 自定义 cell 差不多

image.png


extension CalendarViewController: UICalendarViewDelegate {
    func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
        if dateComponents.day == selectDate.day && dateComponents.year == selectDate.year, dateComponents.month == selectDate.month {
            return UICalendarView.Decoration.customView {
                let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 30.0))
                label.textColor = .red
                label.font = UIFont.systemFont(ofSize: 10.0)
                label.text = "今"
                return label
            }
        } else {
            return .none
        }
    }
}

- UICalendarSelectionSingleDateDelegate 单选模式下代理回调
//MARK: - UICalendarSelectionSingleDateDelegate
extension CalendarViewController: UICalendarSelectionSingleDateDelegate {
    func dateSelection(_ selection: UICalendarSelectionSingleDate, didSelectDate dateComponents: DateComponents?) {
        if let date = dateComponents {
            self.selectDate = date
        }
        print(self.selectDate)
    }
}
- UICalendarSelectionMultiDateDelegate 多选模式下代理回调
extension CalendarViewController : UICalendarSelectionMultiDateDelegate {
     // 选中某个日期回调 跟 tableView didSeselectCellAtIndexPath 类同
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didSelectDate dateComponents: DateComponents) {
        self.selectDate = dateComponents
        print(self.selectDate)
    }
    // 取消选中某个日期回调 跟 tableView didDeselectCell 类同
    func multiDateSelection(_ selection: UICalendarSelectonMultiDate, didDeselectDate dateComponents: DateComponents) {
        
    }
    // 某个日期是否可以选中
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canSelectDate dateComponents: DateComponents) -> Bool {
        return true
    }
    // 某个日期是否可以取消选中
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canDeselectDate dateComponents: DateComponents) -> Bool {
        return true
    }
}

2. UIPageControl 新增API特性

var direction: UIPageControl.Direction // 指示器方向 类型 scrollview 垂直/水平布局
open var preferredIndicatorImage: UIImage? //未选中指示器图片
open var preferredCurrentPageIndicatorImage: UIImage? // 当前选中指示器图片

// 指示器排布方向 
 public enum Direction : Int, @unchecked Sendable {
       /// 页面指示器按系统区域设置的自然方向布置。
       /// 默认情况下,这相当于 LTR 语言环境中的 @c UIPageControlDirectionLeftToRight,并且
        UIPageControlDirectionRightToLeftRTL 语言环境中
        // 大概意思就是如果是从左到右阅读的国家 natural = leftToRight, 如果是从右到左阅读习惯的国家 比如沙特阿拉伯, natural = rightToLeft. 跟文字排版对齐方式 baseLine 区分不同语言文字排版类似
        case natural = 0
        // 从左到右
        case leftToRight = 1
        // 从右到左
        case rightToLeft = 2
        // 从顶部到底部
        case topToBottom = 3
        // 从底部到顶部
        case bottomToTop = 4
    }

从左到右排列

image.png

从右向左排列

image.png

从顶部到底部排列 注意 frame.width 和 frame.height 尺寸 左侧: 从顶部到底部排列 右侧: 从底部到顶部排列

image.png


 let pageControl = UIPageControl(frame: CGRect(x: 0.0, y: 400.0, width: 375.0, height: 50.0))
pageControl.backgroundColor = .lightGray
pageControl.numberOfPages = 5
pageControl.currentPage = 0
pageControl.preferredIndicatorImage = UIImage(named: "pageControlDot")
pageControl.preferredCurrentPageIndicatorImage = UIImage(named: "pageControlCurrentDot")
view.addSubview(pageControl)

3. 新增 UIPasteControl 类

@available(iOS 16.0, *)
其实这就是一个按钮 
@MainActor open class UIPasteControl : UIControl {
    配置信息
    open var configuration: UIPasteControl.Configuration { get }
    目标
    weak open var target: UIPasteConfigurationSupporting?
    构造方法
    public init(configuration: UIPasteControl.Configuration)
    public init?(coder: NSCoder)
    public init(frame: CGRect)
}

 提供了 UIPasteControl 所需要的一些样式
 @MainActor open class Configuration : NSObject, NSSecureCoding {
        展示方式 文字图片摆放位置
        iconAndLabel: 同时显示 label 和 image
        iconOnly: 只显示图片
        labelOnly: 只显示 label
        open var displayMode: UIPasteControl.DisplayMode
        
        open var cornerStyle: UIPasteControl.CornerStyle
        背景颜色
        open var baseForegroundColor: UIColor?
        前景色
        open var baseBackgroundColor: UIColor?
  }

   let button = UIPasteControl()
   button.addTarget(self, action: #selector(paseButtonClick), for: .touchUpInside)
  button.configuration.displayMode = .iconAndLabel
  button.configuration.cornerStyle = .capsule
  button.configuration.baseBackgroundColor = .yellow
  button.configuration.baseForegroundColor = .green       
  button.frame = CGRect(x: 100.0, y: 400.0, width: 100.0, height: 50.0)
  self.view.addSubview(button)

image.png

官方文档也没有讲这个 UIPasteControl 是来做什么的, 猜测跟粘贴板有关, 还有应用顶部粘贴板有内容时 隐私弹窗有关系. 感觉用处不大

4. 在 UIKit 中使用 SwfitUI

WWDC2022很多地方都提到了 SWiftUI, 比如有 70%新提交应用使用了 SWiftUI, iOS 系统 APP 使用了SWiftUI重写, macOS的偏好设置就是用SWiftUI重写的. 从苹果不遗余力的推销SWiftUI 可以看出来, 是时候学习 swiftUI并提高开发效率, 在 what's new in xocde 中有关于 swift 实时预览新特性介绍.

废话不多说 直接上代码 UITableViewCell 支持 SwiftUI 来构造 cell

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "kCellIdentifier", for: indexPath)
        // 把 swfitUI 代码 写到 UIHostingConfiguration 闭包内部
        cell.contentConfiguration = UIHostingConfiguration(content: {
            HStack(alignment: .top) {
                Text("Hello world")
                Image(systemName: "square")
            }
        })
        
        return cell
    }

同样的 UICollectionView 同样有个contentConfiguration 属性, 不再演示给大家了. 只是想告诉大家, 苹果这次真的重视SwiftUI, 让 iOS 程序员从繁杂的 UI 工作中解脱出来, 只需要关注 app 业务本身, 而不是把时间耗在写 UI 调试 UI 上边.

5. 其他的一些新特性

  • 其他还有一些 SF 图片设置颜色 根据进度条显示不同颜色

image.png 跟 swift 并发有关的 API

image.png

image.png

以上内容来源于苹果 WWDC2022 开发者大会 Session, 欢迎大家去收看 developer.apple.com/videos/play…