You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UIActivityViewController中添加额外动作按钮(如Done按钮)

给UIActivityViewController添加同级Done按钮的实现方案

嘿,这个需求确实有点绕——苹果并没有给UIActivityViewController开放直接添加和Cancel同级操作按钮的官方API,但我们可以通过遍历它的内部视图结构来实现,下面是适配iPhone和iPad的具体方案:

核心思路

UIActivityViewController在iPhone上是以底部Sheet形式展示,Cancel按钮放在底部的UIToolbar中;在iPad上则是Popover弹窗,Cancel按钮在导航栏右侧。我们需要针对这两种布局分别处理,找到对应的容器视图后插入自定义的Done按钮。

具体实现步骤

  1. 先持有UIActivityViewController的引用,方便后续操作
  2. 在控制器present完成后,遍历内部视图找到对应的工具栏/导航栏
  3. 创建Done按钮并添加到对应位置,绑定点击事件

完整代码示例

首先在你的ViewController中添加属性:

@property (nonatomic, strong) UIActivityViewController *activityVC;

然后替换你原有的present代码:

// 初始化分享内容
NSArray *shareItems = @[@"你的分享内容"];
self.activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItems applicationActivities:nil];

// 排除不需要的系统活动
NSArray *excludeActivities = @[UIActivityTypePrint, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypePostToWeibo];
self.activityVC.excludedActivityTypes = excludeActivities;

// 设置完成回调
[self.activityVC setCompletionWithItemsHandler:^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
    // 你的原有逻辑处理
}];

// 模态弹出控制器,在完成回调中添加Done按钮
[self presentViewController:self.activityVC animated:YES completion:^{
    [self addCustomDoneButton];
}];

接下来实现添加Done按钮的方法:

- (void)addCustomDoneButton {
    // 先处理iPad的Popover情况
    UINavigationController *navVC = (UINavigationController *)self.activityVC.popoverPresentationController?.presentedViewController;
    if (navVC) {
        // 创建Done按钮,添加到导航栏左侧(也可以加到右侧和Cancel并排)
        UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" 
                                                                    style:UIBarButtonItemStyleDone 
                                                                   target:self 
                                                                   action:@selector(doneButtonTapped:)];
        navVC.navigationItem.leftBarButtonItem = doneItem;
        return;
    }

    // 处理iPhone的Sheet情况,遍历子视图找到底部的UIToolbar
    for (UIView *subview in self.activityVC.view.subviews) {
        if ([subview isKindOfClass:[UIToolbar class]]) {
            UIToolbar *toolbar = (UIToolbar *)subview;
            // 创建Done按钮
            UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" 
                                                                        style:UIBarButtonItemStyleDone 
                                                                       target:self 
                                                                       action:@selector(doneButtonTapped:)];
            // 插入到Cancel按钮的前面(保持布局一致性)
            NSMutableArray *toolbarItems = [toolbar.items mutableCopy];
            [toolbarItems insertObject:doneItem atIndex:toolbarItems.count - 1];
            toolbar.items = toolbarItems;
            break;
        }
    }
}

// Done按钮的点击事件处理
- (void)doneButtonTapped:(UIBarButtonItem *)sender {
    // 关闭分享控制器
    [self.activityVC dismissViewControllerAnimated:YES completion:nil];
    // 这里可以添加你的自定义业务逻辑
}

注意事项

  • 这种方式依赖于UIActivityViewController的内部视图结构,苹果可能在后续iOS版本中调整布局,所以需要在不同系统版本中测试兼容性
  • 如果你的App需要适配iOS 13+的Sheet样式,建议在iOS 13及以上版本中额外做视图层级的校验
  • 如果追求更稳定的实现,也可以考虑自定义一个仿UIActivityViewController的界面,这种方式更可控但开发成本更高

内容的提问来源于stack exchange,提问作者vroldan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:06:58