ios - 在 Swift 中为操作表创建一行多个按钮

标签 ios swift button uiactionsheet

我正在编写一个应用程序,用户可以在其中控制主页上的多个项目,并可以使用箭头按钮或菜单在它们之间切换。但是,我希望能够让用户通过菜单编辑项目的名称,以便当用户导航到菜单时,每一行都有与该行关联的项目的名称,并且在有一个按钮可以弹出警报,让用户更改项目的名称。目前我正在使用操作表来生成项目,但我找不到在行上显示多个项目的方法。我用于生成操作表的代码如下:

@IBAction func tapMGName(_ sender: Any) {
    let actionSheetController: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

    for index in 1...5{
        let addMGSelectAction: UIAlertAction = UIAlertAction(title: "Mouthguard \(index)", style: .default){action -> Void in
            let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let SettingsViewController : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "SettingsViewController") as UIViewController
            self.present(SettingsViewController, animated: false, completion: nil)
        }
        actionSheetController.addAction(addMGSelectAction)
    }
    let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })
    actionSheetController.addAction(cancelAction)
    self.present(actionSheetController, animated: true, completion: nil)

}

What I want the menu to look like

最佳答案

不幸的是,您需要从头开始构建 Controller 。虽然这看起来令人畏惧,但最难的部分是表示逻辑。之后,只需根据用户界面用例对这个主类进行子类化,并在构建时为每个子类提供自己的逻辑即可。

这是自定义 AlertController 的最佳方法: https://gist.github.com/murphman300/4a56ace35d0ccdbf3a0c923b4ec7dc96

您在这里使用像此要点文件中的主类,请注意每个部分的注释。

然后当你对每种类型进行子类化时

//An example subclass of PopUpAlertController
class SpecificAlertControllerSubclass : PopUpAlertController {

    override func set() {
        super.set() //Good idea to call the super., since you might want to add basic stuff all the time, in that case you would do this in the original set() method, not here in the subclass' set() override.

        //Here you add your own content.. that you instantiate in the subclass. The fact set() is being called in viewDidLoad() means you don't need to worry about calling it later on.

    }

}

class TestController : UIViewController, PopUpAlertControllerDelegate {


    var popup : SpecificAlertControllerSubclass?


    func bringUpPopUp() {
        popup = SpecificAlertControllerSubclass()
        popup?.delegate = self
        present(popup!, animated: true) { 
            print("Popup Presented")
        }
    }


    /*
     The Delegate methods you will always need to consider when using it.
    */

    func popUp(controller: PopUpAlertController, didDismiss withInfo: Any?) {
        if let pop = popup, controller == pop {
            //checks if the delegated controller is popup..
            popup = nil
            let info = withInfo != nil ? String(describing: withInfo!) : "unknown"
            print("Dismissed PopUp, with reason: \(info)")
        }
    }

    func popUp(controller: PopUpAlertController, selected item: [String : Any]?) {
        //Here is where you would handle the user selecting one of your options. Dismissing the popup andPresenting another controller. or if you want the popup subclass to handle the logic and the next controller, you don't call this method, but handle it in the subclass object.
    }

}

因此这将以与 UIAlertControllers 相同的方式弹出一个 View 。然而,它的外观完全取决于你。使用此类时需要记住的一些事项:

  1. 在设置覆盖中设置弹出 View 的初始位置。
  2. set()覆盖:始终记住您要将 subview 添加到 popUp查看,不给view 。当然,你可以将popUp重命名为 无论你想要什么..
  3. 如果您想更改 Controller 的呈现方式,您需要 更改子类中的覆盖和表示变量,而不是主类。那 这样你就可以保持通用的完整以便快速重复使用,但是你的 具体用例仍然可以区分。
  4. 我发现最重要的是 viewDidAppear如果在以下时间完成会更有用 子类级别,原因与上一点相同。你 可以在那里插入单独的演示方法。
  5. 要更改解雇动画,您必须覆盖 方法本身,无需在重写中调用 super。

第 3 点和第 4 点意味着 SpecificAlertControllerSubclass变成这样:

class SpecificAlertControllerSubclass : PopUpAlertController {

    override func set() {
        super.set() //Good idea to call the super., since you might want to add basic stuff all the time, in that case you would do this in the original set() method, not in the subclasses.

        //Here you add your own content..

        modalPresentationStyle = //which ever one you want

        modalTransitionStyle = //which ever one you want

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .allowAnimatedContent, animations: {
            self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
            self.popUp.alpha = 1
        }) { (v) in

        }
    }

}

就像对第二个委托(delegate)方法的评论所解释的那样,您需要决定哪个 Controller 应该处理操作逻辑,在我看来,这取决于您在按下这些操作时是否呈现新 Controller ,或者您只是切换用户界面。在后一种情况下,您可以从 PopUpAlertController 中创建 didSelect 方法。 protocol一种可选方法。 Here's a good tutorial on delegates .

我还将 popUp 的 alpha 设置为 0,这是针对您的用例,即中心屏幕淡入效果。当然,如果你想让弹出窗口滑入,你可以改变set()中的alpha值。覆盖。如果你还想要动画幻灯片,你只需要在 set() 中设置 popUp 的初始位置即可。覆盖,并在 viewDidAppear 中您希望它出现的位置设置动画。覆盖。因此,这种方法确实要求您跟踪如何在子类中更改主类的属性,但是,当您掌握了它的窍门后,它的可定制性非常好。

从这里,你几乎可以做任何你想做的事情。只需记住在选择操作时处理弹出窗口的 ui 过渡,以确保过渡平滑等。

至于你想要的外观。我认为你最好的方法是使用 UITableView具有全长边框,或 UICollectionView 。您应该在 PopUpAlertController 中委托(delegate)您决定的任何一个,并用它们各自的 didSelectItemAt 解释选择方法。方法并调用PopUpAlertControllerDelegatepopUp(controller: PopUpAlertController, didDismiss withInfo: Any?) 。这将允许您为每一行设置自定义图标。

这是一个关于以编程方式完成 UICollectionView 的很好的教程: https://www.youtube.com/watch?v=3Xv1mJvwXok&list=PL0dzCUj1L5JGKdVUtA5xds1zcyzsz7HLj

关于ios - 在 Swift 中为操作表创建一行多个按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45060923/

相关文章:

ios - iOS模拟器问题应用仅在第二次启动时运行。

ios - 实现类似于 UICollectionView 的 "registerClass"

android - 处于 Activity 状态时,按钮不会重绘 (Android Webkit)

ios - Swift - 添加按钮操作后无法从 TableView 重新加载数据

ios - Swift 中的群组电话 session

ios - 如何只读取一次文件数量?

ios - 从 API 和 coredata 调用文本会导致 exc_bad_access

arrays - 如何在 Swift 中分割字符串并保留分隔符?

android - 如何在android中的一个按钮中放置2个不同的文本?

javascript - 更改按钮颜色