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

相关推荐
大熊猫侯佩2 小时前
SwiftUI Charts 入门:从零到一,笑谈“柱”状人生(二)
swiftui·swift·apple
大熊猫侯佩2 小时前
SwiftUI Charts 入门:从零到一,笑谈“柱”状人生(三)
swiftui·swift·apple
大熊猫侯佩2 小时前
SwiftUI Charts 入门:从零到一,笑谈“柱”状人生(一)
swiftui·swift·apple
我现在不喜欢coding5 小时前
混乱的scheme、.xcconfig、build Settings梳理的清清楚楚
ios·xcode
ls_qq_267081347011 小时前
cocos打包web - ios设备息屏及前后台切换音频播放问题
前端·ios·音视频·cocos-creator
归故里11 小时前
[swift] 用泛型整合 Codable 和 文件读写!
swift
不爱说话郭德纲13 小时前
别再花冤枉钱!手把手教你免费生成iOS证书(.p12) + 打包IPA(超详细)
前端·ios·app
iOS阿玮13 小时前
凭一己之力干穿一个品牌,互联网+时代口碑比以前更重要了!
uni-app·app·apple
杂雾无尘14 小时前
Vision Pro 新手教学:SwiftUI 实现 3D 应用的技巧,基础篇
ios·swiftui·visionos
谈吐大方的鹏sir1 天前
SwiftUI中的状态管理
ios