iOS-8及以上版本 - 在UIAlertController中嵌入UITableView

5

我知道如何通过使用accessoryViewUITableView一样在UIAlertView中添加任何Custom UI,但我现在很好奇是否仍有选项可以在UIAlertController中添加Custom UI。我想要的是在UIAlertController中放置一个UITableViewController,并且希望能够清楚地理解。


我已经在iOS 7中尝试过,但没有在iOS 8中。 - Syed Ali Salman
你在 UIAlertController 中尝试过了吗? - Wez
UIAlertController 中没有这样的选项。 - Syed Ali Salman
3
https://dev59.com/k18e5IYBdhLWcg3wS425 - Agent Chocks.
4个回答

27
感谢StackOverflow用户的帮助,我已经完成了这个任务。
以下是我的代码:
UIViewController *controller = [[UIViewController alloc]init];
UITableView *alertTableView;
CGRect rect;
if (array.count < 4) {
    rect = CGRectMake(0, 0, 272, 100);
    [controller setPreferredContentSize:rect.size];

}
else if (array.count < 6){
    rect = CGRectMake(0, 0, 272, 150);
    [controller setPreferredContentSize:rect.size];
}
else if (array.count < 8){
    rect = CGRectMake(0, 0, 272, 200);
    [controller setPreferredContentSize:rect.size];

}
else {
    rect = CGRectMake(0, 0, 272, 250);
    [controller setPreferredContentSize:rect.size];
 }

alertTableView  = [[UITableView alloc]initWithFrame:rect];
alertTableView.delegate = self;
alertTableView.dataSource = self;
alertTableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
[alertTableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[alertTableView setTag:kAlertTableViewTag];
[controller.view addSubview:alertTableView];
[controller.view bringSubviewToFront:alertTableView];
[controller.view setUserInteractionEnabled:YES];
[alertTableView setUserInteractionEnabled:YES];
[alertTableView setAllowsSelection:YES];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
[alertController setValue:controller forKey:@"contentViewController"];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {

}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];

Checkout the snapshot here ;)


将DRY原则应用于代码中,将alertTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 272, xxx)从if语句中取出,并替换为alertTableView = [[UITableView alloc]initWithFrame:rect]; - pqteru
我发现了UIAlertController警告框的宽度。 - Syed Ali Salman
1
太棒了,救了我的一天!非常感谢! - PakitoV

9
这是@Syed Ali Salman的答案的简化版,使用Swift编写:

这里是@Syed Ali Salman's answer

let alertController = UIAlertController(title: "The Title",
                                        message: "Here's a message.",
                                        preferredStyle: .Alert)

let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel)
{ (action) in
    // ...
}
alertController.addAction(cancelAction)

let okAction = UIAlertAction(title: "OK", style: .Default)
{ (action) in
    // ...
}
alertController.addAction(okAction)

let tableViewController = UITableViewController()
tableViewController.preferredContentSize = CGSize(width: 272, height: 176) // 4 default cell heights.
alertController.setValue(tableViewController, forKey: "contentViewController")

yourTopViewController().presentViewController(alertController, animated: true)
{
    // ...
}

6
UIViewController *tempViewController = [[UIViewController alloc] init];
    tempViewController.view.backgroundColor = [UIColor redColor];

    [alertController setValue:tempViewController forKey:@"contentViewController"];

那段代码将在警告视图上显示一个红色视图,现在您可以轻松地在UIViewController内放置UITableView。开心地定制UIAlertController ;)

当你完成时,这理论上应该可以工作,请向我们展示一个性感的截图 ^^ - Gil Sand
@Zil,请检查我下面的答案。 - Syed Ali Salman

1

这是一个 Swift 5 的示例代码:

    //MARK: - Properties
    private var alertController = UIAlertController()
    private var tblView = UITableView()

    //MARK: - TableViewAlert
    private func setupTableViewAlert() {
    
    let alertVC = UIViewController.init()
    let rect = CGRect(x: 0.0, y: 0.0, width: 300.0, height: 300.0)
    alertVC.preferredContentSize = rect.size
    
    tblView = UITableView(frame: rect)
    tblView.delegate = self;
    tblView.dataSource = self;
    tblView.tableFooterView = UIView(frame: .zero)
    tblView.separatorStyle = .singleLine
    alertVC.view.addSubview(tblView)
    alertVC.view.bringSubviewToFront(tblView)
    alertVC.view.isUserInteractionEnabled = true
    tblView.isUserInteractionEnabled = true
    tblView.allowsSelection = true
    
    self.alertController = UIAlertController(title: "Select City", message: nil, preferredStyle: .alert)

    //this is the main part
    //add local alert content over global one
    alertController.setValue(alertVC, forKey: "contentViewController")
    
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    
    alertController.addAction(cancelAction)
    self.present(alertController, animated: true, completion: nil)
}


extension SignupViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell = UITableViewCell.init(style: .value1, reuseIdentifier: "cell")
    cell.textLabel?.text = "Cell \(indexPath.row + 1)"
    cell.textLabel?.textAlignment = .center
    cell.detailTextLabel?.textColor = .black
    return cell
}}

输入图片描述


我看到你是一个新的贡献者,感谢你的回答。你能否在解决方案中增加一些细节呢? - Mahesh H Viraktamath
@MaheshHViraktamath,请检查这是否合适,如果需要编辑请随意。 - Jaipee1
这是错误的建议。引用自苹果的文档:UIAlertController类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。 - Gereon
@Gereon 如果您有更好的解决方案,请与我们分享。 - Jaipee1
快速而简单,谢谢 :) - masaldana2
@masaldana2如果您有其他完美的解决方案,请与我们分享。谢谢。 - Jaipee1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接