这里每天分享一个 iOS 的新知识,快来关注我吧
前言
在前两篇文章中,我们分别介绍了如何在 iOS 应用中添加分享扩展,以及如何通过 info.plist 配置文件来限定分享内容的格式。今天,我们将继续深入,探讨如何自定义 ShareViewController 的用户界面(UI),从而提升用户在分享过程中的体验。
往期内容:
iOS 分享扩展(一):如何让你的 App 出现在 iOS 系统的分享面板中
iOS 分享扩展(二):info.plist 文件配置全解析
初识 ShareViewController 的 UI
默认情况下,Xcode 为我们生成的 ShareViewController 是基于 SLComposeServiceViewController
的,这个类提供了一些基础的 UI 组件,比如文本输入框和附件预览。然而,这些默认组件可能无法满足应用的个性化需求,因此我们需要对其进行定制。
默认 ShareViewController 示例
以下是我们在项目中自动生成的 ShareViewController
代码:
swift
import UIKit
import Social
class ShareViewController: SLComposeServiceViewController {
override func isContentValid() -> Bool {
return true
}
override func didSelectPost() {
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
override func configurationItems() -> [Any]! {
return []
}
}
自定义 UI 的步骤
1. 使用自定义 View
为了自定义分享页面的 UI,我们可以选择创建一个新的 UIView,并将其添加到 ShareViewController 的视图层次结构中。首先,我们需要创建一个新的 UIView 子类,用于定义自定义 UI 元素。
swift
import UIKit
class CustomShareView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
// 设置背景颜色
self.backgroundColor = UIColor.systemGray6
// 添加自定义子视图,如标签和按钮
let label = UILabel()
label.text = "分享你的内容"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(label)
// 使用自动布局设置位置
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: self.centerXAnchor),
label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
}
}
2. 在 ShareViewController 中加载自定义 View
接下来,我们在 ShareViewController
中使用这个自定义视图。我们需要在 viewDidLoad
方法中添加代码,将 CustomShareView
加载到视图控制器的视图中。
swift
override func viewDidLoad() {
super.viewDidLoad()
// 移除自带的文本输入框
self.textView.removeFromSuperview()
// 添加自定义视图
let customShareView = CustomShareView(frame: self.view.bounds)
customShareView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(customShareView)
// 设置自动布局
NSLayoutConstraint.activate([
customShareView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
customShareView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
customShareView.topAnchor.constraint(equalTo: self.view.topAnchor),
customShareView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
}
3. 添加交互功能
我们可以在自定义视图中添加按钮、输入框等交互元素,并在 ShareViewController 中实现其功能。例如,添加一个确定分享的按钮和一个取消分享的按钮,来执行自定义的分享操作:
swift
class CustomShareView: UIView {
var shareButtonAction: (() -> Void)?
var cancelButtonAction: (() -> Void)?
private func setupView() {
// 其他视图设置...
let cancelButton = UIButton(type: .system)
cancelButton.setTitle("取消", for: .normal)
cancelButton.addTarget(self, action: #selector(cancelButtonTapped), for: .touchUpInside)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(cancelButton)
// 设置按钮位置
NSLayoutConstraint.activate([
cancelButton.centerXAnchor.constraint(equalTo: self.centerXAnchor),
cancelButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -60)
])
let shareButton = UIButton(type: .system)
shareButton.setTitle("分享", for: .normal)
shareButton.addTarget(self, action: #selector(shareButtonTapped), for: .touchUpInside)
shareButton.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(shareButton)
// 设置按钮位置
NSLayoutConstraint.activate([
shareButton.centerXAnchor.constraint(equalTo: self.centerXAnchor),
shareButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20)
])
}
@objc
private func shareButtonTapped() {
shareButtonAction?()
}
@objc
private func cancelButtonTapped() {
cancelButtonAction?()
}
}
在 ShareViewController
中,设置一下这两个按钮的操作:
swift
override func viewDidLoad() {
super.viewDidLoad()
// 其他视图设置...
let customShareView = CustomShareView(frame: self.view.bounds)
customShareView.shareButtonAction = {
self.performCustomShare()
}
customShareView.cancelButtonAction = {
self.extensionContext!.cancelRequest(withError: NSError(domain: "CustomShare", code: 1, userInfo: [NSLocalizedDescriptionKey: "用户取消分享"]))
}
self.view.addSubview(customShareView)
}
private func performCustomShare() {
// 执行自定义分享逻辑
print("执行自定义分享操作")
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
然后,我们可以把用户分享的内容读出来,显示在自定义视图的 UILabel 中,我这里还是以 URL 为例:
swift
override func viewDidLoad() {
super.viewDidLoad()
// 其他视图设置...
let customShareView = CustomShareView(frame: self.view.bounds)
customShareView.shareButtonAction = {
self.performCustomShare()
}
customShareView.cancelButtonAction = {
self.extensionContext!.cancelRequest(withError: NSError(domain: "CustomShare", code: 1, userInfo: [NSLocalizedDescriptionKey: "用户取消分享"]))
}
self.view.addSubview(customShareView)
// 读取用户分享的内容
if let item = self.extensionContext?.inputItems.first as? NSExtensionItem,
let itemProvider = item.attachments?.first as? NSItemProvider,
itemProvider.hasItemConformingToTypeIdentifier("public.url") {
itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil) { (url, error) in
if let url = url as? URL {
DispatchQueue.main.async {
customShareView.shareContent = url.absoluteString
}
}
}
}
}
在 CustomShareView
中,添加一个 shareContent
属性,用于保存用户分享的内容:
swift
var shareContent: String? {
didSet {
if let shareContent {
self.contentLabel?.text = "你要分享的内容为:\(shareContent)"
}
}
}
如果你的应用分享更复杂的内容,也可以更定制化的添加更多内容,比如图片、视频等,这里就不一一列举了。最后看一下效果:

总结
通过自定义 ShareViewController 的 UI,我们可以为用户提供更为个性化和友好的分享体验。在今天的文章中,我们介绍了如何创建自定义视图,并将其集成到分享扩展中。希望这篇文章能为你的应用开发提供一些灵感和帮助。
在接下来的文章中,我们将继续探讨更多关于 iOS 分享扩展的高级特性。感谢你的关注和阅读!如果有任何问题或建议,欢迎留言与我交流。
这里每天分享一个 iOS 的新知识,快来关注我吧
本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!