Swift UIAlertController 文件重命名操作
Posted
技术标签:
【中文标题】Swift UIAlertController 文件重命名操作【英文标题】:Swift UIAlertController file rename action 【发布时间】:2015-09-09 15:53:29 【问题描述】:我使用的是 Swift 2。这个问题与 ios9 有关。
简而言之:-
如果点击了文件重命名按钮,但文件名仍然无效,那么我需要再次显示警报还是有更聪明的方法来处理这个问题?
全文:-
保存从 iCloud 导入的文件,如果 /Documents
中已存在同名文件 (.lastPathComponent
),我将提供一个名为 alertController
的 UIAlertController
。
UIAlertController
有两个名为 Cancel
和 Rename
的操作以及一个 .addTextFieldWithConfigurationHandler
。如果文件名已经存在,则提示用户取消或重命名。
此问题涉及验证新名称并重新呈现(或不关闭)UIAlertController,直到文件名有效:
如果用户单击重命名按钮并且文件名仍然相同,或者与另一个已经存在的文件相同,那么我希望再次显示 UIAlertController。或者更好的是,在文件名有效之前它不会被关闭。
我做到这一点的方法(我想出的唯一方法)是添加一个名为presentAlertController
的func
,它表示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 标题高度