iOS 分享扩展(三):轻松定制 iOS 分享界面,提升用户体验

这里每天分享一个 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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
zjam93334 小时前
iOS 26 又有新的属性监听方法啦?
ios
鹤渺5 小时前
React Native 搭建iOS与Android开发环境
android·react native·ios
iOS阿玮8 小时前
Pingpong和连连的平替,让AppStore收款无需新增持有人。
uni-app·app·apple
Digitally12 小时前
如何将数据从安卓设备传输到 iPhone | 综合指南
android·ios·iphone
大熊猫侯佩13 小时前
漫谈初学者处理 CoreData 数据之启示录
数据库·debug·swift
Pitayafruit13 小时前
写给尊贵的 Tare Pro 用户的喂饭级 IOS APP 开发指南
ios·ai编程·trae
大熊猫侯佩13 小时前
Xcode 15.0 新 #Preview 预览让 SwiftUI 界面调试更加悠然自得
swiftui·swift·apple
openinstall1 天前
A/B测试如何借力openinstall实现用户价值深挖?
android·ios·html