WWDC Quick Look 💓 By SwiftGGTeam
Meet the Location Button

Meet the Location Button

观看原视频

Highlight

iOS 15 引入 CLLocationButton,用户点击按钮即可授予应用一次性位置授权,无需经过传统的系统权限弹窗,让”仅需偶尔定位”的场景获得更低摩擦的用户体验。

核心内容

很多应用只需要在特定时刻获取一次用户位置。查找附近公园、查询最近门店、签到打卡——这些场景不需要持续追踪用户动向。

但传统的位置授权流程对这些场景很不友好。应用一启动就弹出权限请求,用户面对”使用期间允许""允许一次""不允许”三个选项,往往因为不确定应用会如何使用位置数据而选择拒绝。一旦点了”不允许”,应用后续所有位置功能都无法使用,用户还得去设置里手动开启。

iOS 15 的 CLLocationButton 改变了这个流程。

开发者把按钮放在用户明确需要位置信息的界面——比如”查找附近公园”按钮旁边。用户点击后,系统直接授予一次性的 Allow-Once 授权,应用立即获得位置数据。没有弹窗干扰,用户心理负担也更小。

这个按钮由系统渲染,带有标准的位置箭头图标和”Current Location”标签,保证用户能识别这是一个位置相关的操作。状态栏上的位置箭头会短暂变蓝,提示用户刚刚授权了位置访问。

对于之前选择了”不允许”的用户,点击 Location Button 会触发一个引导提示,给用户机会将应用的状态重置为”未决定”,重新使用 Location Button 获取位置。这让被误杀的应用有了一次”复活”的机会。

watchOS 8 还新增了基于地理围栏的用户通知(Region-based user notifications),应用在用户到达特定地点时推送通知,无需”始终”位置授权。

详细内容

UIKit 中的 CLLocationButton

04:09)CLLocationButton 属于 CoreLocationUI 框架,继承自 UIControl,用法和普通 UIButton 类似。

四个专属属性:

  • icon:设置箭头类型(arrowFilledarrowOutline
  • label:设置按钮标签(.currentLocation.sendCurrentLocation.none
  • cornerRadius:圆角大小
  • fontSize:标签字体大小

从 UIButton 迁移到 CLLocationButton 的对比:

// 原来的 UIButton 方式
let button = UIButton()
button.setTitle("Current Location", for: .normal)
button.addTarget(self, action: #selector(showNearbyParks), for: .touchUpInside)

func showNearbyParks() {
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
    // ... 渲染地图
}
// 新的 CLLocationButton 方式
let locationButton = CLLocationButton()
locationButton.label = .currentLocation
locationButton.addTarget(self, action: #selector(showNearbyParks), for: .touchUpInside)

func showNearbyParks() {
    // 不需要再调用 requestWhenInUseAuthorization
    // 点击按钮时系统自动授予一次性授权
    locationManager.startUpdatingLocation()
    // ... 渲染地图
}

关键点:

  • 创建 CLLocationButton 替代 UIButton
  • 设置 label 属性定义按钮文字
  • 不再需要调用 requestWhenInUseAuthorization,按钮点击自动处理授权
  • 其他业务逻辑保持不变

SwiftUI 中的 LocationButton

06:30)SwiftUI 提供了原生 LocationButton:

import CoreLocationUI

struct ParkFinderView: View {
    @StateObject var locationManager = LocationManager()

    var body: some View {
        LocationButton(.currentLocation) {
            locationManager.requestLocation()
        }
        .symbolVariant(.fill)
        .tint(.blue)
    }
}

关键点:

  • LocationButton 是 SwiftUI 原生视图
  • 第一个参数是标签类型,闭包中是点击后的业务逻辑
  • .symbolVariant(.fill) 设置实心箭头图标
  • .tint(.blue) 设置按钮背景色

自定义样式与限制

06:53)CLLocationButton 支持自定义外观,但系统会检查可读性:

let button = CLLocationButton()
button.icon = .arrowFilled
button.tintColor = .black
button.backgroundColor = .white
button.cornerRadius = 25.0

关键点:

  • 默认样式:白色文字、蓝色背景、“Current Location”标签
  • 可以修改前景色、背景色、圆角
  • 当宽高相等且 cornerRadius 为宽度的一半时,可得到圆形按钮

系统会在以下情况阻止授权并输出日志:

  • 按钮尺寸过小或文字超出按钮范围
  • 透明度(alpha)过低,影响可识别性
  • 前景色和背景色对比度不足

Xcode 的 Issue Navigator 会实时显示这些可读性问题,方便开发者调试。

授权状态交互

10:55)Location Button 对现有授权状态的影响:

当前授权状态使用 Location Button 后的行为
NotDetermined首次点击出现确认提示,之后每次点击直接授予一次性授权
While Using不影响现有授权,行为与普通按钮相同
Don’t Allow点击后出现引导提示,可将状态重置为 NotDetermined

关键点:

  • Location Button 本质上是 Allow-Once 授权
  • 用户在隐私设置中会看到”When I Share”选项
  • 已有”使用期间”授权的应用不受影响
  • 被永久拒绝的应用可以通过 Location Button”复活”

核心启发

  • 附近查找功能优化:在”查找附近餐厅/加油站/充电桩”的场景中,用 CLLocationButton 替代传统授权弹窗。用户点击按钮时才请求位置,转化率比启动时弹窗更高。入口 API:CLLocationButton() + startUpdatingLocation()

  • 签到打卡场景:在考勤、旅行打卡、运动记录等”一次性定位”场景中,把 Location Button 放在打卡按钮旁边。用户明确知道点击后会获取位置,心理接受度更高。配合 CLGeocoder 反向解析地址显示给用户确认。

  • 被禁用的应用召回:对于之前被用户拒绝定位权限的应用,在需要位置的界面展示 Location Button。用户点击后系统会引导重置授权状态,给应用第二次机会。这比让用户去设置里手动开启容易得多。

  • watchOS 地理围栏通知:在 Apple Watch 应用中使用 Region-based notifications,用户到达健身房时提醒开始锻炼,到家时提醒喂狗。无需”始终”授权,系统代为监控地理位置并触发通知。

关联 Session

评论

GitHub Issues · utterances