Swift UIAlertController 文件重命名操作

Posted

技术标签:

【中文标题】Swift UIAlertController 文件重命名操作【英文标题】:Swift UIAlertController file rename action 【发布时间】:2015-09-09 15:53:29 【问题描述】:

我使用的是 Swift 2。这个问题与 ios9 有关。

简而言之:-

如果点击了文件重命名按钮,但文件名仍然无效,那么我需要再次显示警报还是有更聪明的方法来处理这个问题?


全文:-

保存从 iCloud 导入的文件,如果 /Documents 中已存在同名文件 (.lastPathComponent),我将提供一个名为 alertControllerUIAlertController

UIAlertController 有两个名为 CancelRename 的操作以及一个 .addTextFieldWithConfigurationHandler。如果文件名已经存在,则提示用户取消或重命名。

此问题涉及验证新名称并重新呈现(或不关闭)UIAlertController,直到文件名有效:

如果用户单击重命名按钮并且文件名仍然相同,或者与另一个已经存在的文件相同,那么我希望再次显示 UIAlertController。或者更好的是,在文件名有效之前它不会被关闭。

我做到这一点的方法(我想出的唯一方法)是添加一个名为presentAlertControllerfunc,它表示UIAlertController。如果文件名已存在(或未更改),则在单击按钮时从重命名处理程序调用此 func。 (与从动作中再次显示 UIAlertController 相同)。

我的问题:-

我的代码可以满足我的要求,但任何人都可以提出一种更简洁、更简洁的方式来实现此结果 - 无需再次显示 UIAlertController

这里是相关代码。请注意,这整个部分都在另一个函数的完成处理程序中 - 因此需要对self 的各种引用以及为什么UIAlertController 代码在dispatch_async(dispatch_get_main_queue()) 中(必须从主队列中调用)。

//...
if checkFileExists(saveURL)  // saveURL: NSURL
    dispatch_async(dispatch_get_main_queue()) 
        let message = "File named `\(saveURL.lastPathComponent!)` already exists. Please import using a new name or else cancel."
        let alertController = UIAlertController(title: "", message: message, preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addTextFieldWithConfigurationHandler  textField -> Void in
            textField.text = saveURL.lastPathComponent! // it presents a text field containing the file name which needs to be changed
        

        func presentAlertController() 
            self.presentViewController(alertController, animated: true) 
        

        alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))

        alertController.addAction(UIAlertAction(title: "Rename", style: .Default)  action -> Void in
            saveURL = saveURL.URLByDeletingLastPathComponent!.URLByAppendingPathComponent((alertController.textFields?.first!.text)!)
            if checkFileExists(saveURL) 
                presentAlertController() // currently it is calling a function to present the UIAlertController again if the file still exists when the button is clicked
             else 
                saveXML(saveURL, dataObject: self.myThing)
                self.fileTableView.reloadData()
            
        )
        presentAlertController() // this will be the first time that this called
    

//...

【问题讨论】:

【参考方案1】:

因此,您可以向文本字段添加一个目标,该目标将在编辑文本字段时调用,并且在该函数中您可以检查用户是否输入了有效名称。您将遇到的问题是您需要访问alertController,以便您可以禁用“重命名”按钮。您可以通过在视图控制器的顶部创建一个属性来实现这一点,如下所示:

var alertController: UIAlertController!

然后修改您发布的代码,如下所示:

//...
if checkFileExists(saveURL)  // saveURL: NSURL
    dispatch_async(dispatch_get_main_queue()) 
        let message = "File named `\(saveURL.lastPathComponent!)` already exists. Please import using a new name or else cancel."
        //just assigning here, not redeclaring (get rid of "let")
        alertController = UIAlertController(title: "", message: message, preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addTextFieldWithConfigurationHandler  textField -> Void in
            textField.text = saveURL.lastPathComponent! // it presents a text field containing the file name which needs to be changed
            //Add the target here, calls on checkString
            textField.addTarget(self, action: "checkString:", forControlEvents: UIControlEvents.EditingChanged)
        

        func presentAlertController() 
            self.presentViewController(alertController, animated: true) 
        

        alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))

        alertController.addAction(UIAlertAction(title: "Rename", style: .Default)  action -> Void in
            saveURL = saveURL.URLByDeletingLastPathComponent!.URLByAppendingPathComponent((alertController.textFields?.first!.text)!)
            if checkFileExists(saveURL) 
                presentAlertController() // currently it is calling a function to present the UIAlertController again if the file still exists when the button is clicked
             else 
                saveXML(saveURL, dataObject: self.myThing)
                self.fileTableView.reloadData()
            
        )
        //Disable the "Rename" button to start, remove this line if you don't want that to happen
        (alertController.actions as! [UIAlertAction])[1].enabled = false
        presentAlertController() // this will be the first time that this called
    

//...

然后您必须创建一个checkString 函数(显然,您可以随意重命名它,只要您还更改了将目标添加到文本字段的行上的选择器)。这里有一些代码可以给你一个想法,但是你必须在这里写你自己的东西。

func checkString(sender: UITextField) 
    //Pretty safe assumption you don't want an empty string as a name
    if sender.text == "" 
        (alertController.actions as! [UIAlertAction])[1].enabled = false
    
    //As soon as the user types something valid, the "Rename" button gets enabled
    else 
        (alertController.actions as! [UIAlertAction])[1].enabled = true
    

此代码已经过测试,但不是很严格,如果您有问题或是否有效,请发表评论。

【讨论】:

投了你一票。感谢您花时间提供一个好的答案。在这种情况下,我认为有 2 个问题:对于每个按键 UIControlEvents.EditingChanged 及其目标都会被调用。这意味着 - checkFileExists(saveURL) 每次按键 - 这看起来很乱。也意味着改变saveURL 的范围——因为我认为目标函数需要在完成处理程序之外。仅供参考 - 对于稍后阅读本文的任何人,今天当前的语法是 textField.addTarget(self, action: Selector("checkString:"), forControlEvents: UIControlEvents.EditingChanged) - 可能会再次更改!

以上是关于Swift UIAlertController 文件重命名操作的主要内容,如果未能解决你的问题,请参考以下文章

swift UIAlertController使用 UIAlertController的宽度 为270

如何在 Swift 中旋转 UIAlertController

Swift:UIAlertController 在 while 循环中

Swift 如何获取 UIAlertController 标题高度

UiAlertView 或 UiAlertController 在 Swift 中仅显示一次

Swift3:在 SKView 中添加 UIAlertController