2017-07-12 45 views
0

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

@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

+0

所以基本上,你有显示图标的问题? – murphguy

+0

如果这就是你想要做的,你不能将图标添加到UIAlertController,因为这些是操作系统级别的UI元素(如触摸ID,应用程序权限请求等)。如果您希望具有更多可定制内容的Alert视图,您将不得不自行构建。我会发布一个答案,以您需要的方式实现这个程序化的基础(相信我,以故事板的形式编程自定义弹出视图更容易)。最终你会想要创建这样的东西:https://raw.githubusercontent.com/dogo/SCLAlertView/master/ScreenShots/ScreenShot2.png – murphguy

+0

我在显示同一行上的多个项目时遇到问题,操作表看起来像它只支持每行一个动作,但我想要两个!非常感谢! – Chris

回答

0

不幸的是,你需要从头开始构建控制器。虽然看起来令人生畏,但最难的部分是呈现逻辑。之后它只是将这个主类用于每个ui用例的子类,并为这些子类中的每个子类创建自己的逻辑。

这里有一个自定义AlertControllers您的最佳方法: 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视图。但是,它的外观完全取决于你。使用这种类别时需要记住的某些事项:

  1. 在设置覆盖中设置弹出视图的初始位置。
  2. set()覆盖:总是记住你要添加子视图 popUp视图,而不是view。当然,您可以将弹出窗口重命名为 。
  3. 如果要更改控制器的显示,您需要 来更改子类中的覆盖和表示变量,而不是主类。那你可以保持一般的完整,以便快速重用,但是你的特定用例仍然是可区分的。
  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 

     } 
    } 

} 

喜欢上了第二委托方法解释了评论,你需要决定哪个控制器应该处理的行动逻辑,在我看来, ,具体取决于在按下这些操作时是否显示新控制器,或者只是切换UI。在后面的情况下,可以使PopUpAlertController 的didSelect方法成为可选方法。 Here's a good tutorial on delegates

我还将popUp的alpha设置为0,这是针对您的用例,它是一个中心屏幕淡入效果。当然,如果你想让弹出窗口滑入,你可以在set()覆盖中更改该alpha值。如果您还想在动画中滑动幻灯片,则只需在set()覆盖中设置弹出窗口的初始位置,然后将其设置为在viewDidAppear覆盖中出现的位置进行动画处理。因此,从这个方面来看,这种方法确实需要你跟踪你如何改变你的子类中的主类的属性,但是,当你掌握它的时候,它的可定制性是非常整洁的。

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

至于你想要的外观。我认为你最好的选择是使用带有全长边框的UITableViewUICollectionView。您应该委派您在PopUpAlertController中决定使用哪种方法,使用其各自的didSelectItemAt方法解释选择方法,并调用PopUpAlertControllerDelegatepopUp(controller: PopUpAlertController, didDismiss withInfo: Any?)。这将允许您为每一行设置自定义图标。

这里有UICollectionView一个很好的教程的编程方式: https://www.youtube.com/watch?v=3Xv1mJvwXok&list=PL0dzCUj1L5JGKdVUtA5xds1zcyzsz7HLj

+0

有没有一种方法可以通过编程创建一个动作表,让您自定义它?我不想打开一个全新的视图控制器,如果可能的话,我想制作一个类似于本视频中制作的操作表,https://www.youtube.com/watch?v=wLjxX7PAF6E&t=614s ,但是我希望每行都有两个动作,一个会更改UI,另一个允许您编辑行的名称,因为每一行的名称都只是您要导航的护牙的名称。 – Chris

相关问题