UIViewController のサブクラスとして3つのクラスを生成します。 それぞれのクラス名とファイル名は次のようにします。
クラス名 | subclass of: | ファイル名 |
FileAdd | UIViewController | FileAdd.swift |
FileList | UIViewController | FileList.swift |
FileSelect | UIViewController | FileSelect.swift |
project navigator のプロジェクト名の上でマウスを右ドラッグして "New File..." を選択します。 iOS の Source で Cocoa Touch Class を選んで Next をクリックします。 Class: には "FileList", Subclass of: には "UIViewController" Language: には "Swift" を選びます(クラス名は自由に選んで構いません)。 FileList.swift がプロジェクトに追加されます。
これをもう2回繰り返して、合計で3つのファイルを追加します。
UIView オブジェクト | connection | 変数名またはメソッド名 |
Button | Action (Touch Up Inside) | tapBack()関数 |
Table View | Outlet | myTableView |
UIView オブジェクト | connection | 変数名またはメソッド名 |
Label | Outlet | myLabel変数 |
Text View | Outlet | myTextView |
"Back" Button | Action (Touch Up Inside) | tapBack()関数 |
"Remove" Button | Action (Touch Up Inside) | tapRemove()関数 |
UIView オブジェクト | connection | 変数名またはメソッド名 |
Text Field | Outlet | myTextField |
Text View | Outlet | myTextView |
"Back" Button | Action (Touch Up Inside) | tapBack()関数 |
"Add File" Button | Action (Touch Up Inside) | tapAdd()関数 |
"Make Dir" Button | Action (Touch Up Inside) | tapMkdir()関数 |
ViewController.swiftに追加するコード(赤字部分) |
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
FileList.swiftに追加するコード(赤字部分) |
import UIKit class FileList: UIViewController, UITableViewDataSource, UITableViewDelegate { var manager: NSFileManager! var fullPath: String! var paths: Array<String>! @IBOutlet weak var myTableView: UITableView! @IBAction func tapBack(sender: AnyObject) { dismissViewControllerAnimated(true, completion: nil) } func tableView(tableView: UITableView, numberOfRowsInSection section:Int) -> Int { if paths == nil { return 1 } return paths.count; } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell") cell.textLabel?.text = paths[indexPath.row] return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let storyboard = UIStoryboard(name:"Main",bundle:nil) let controller: FileSelect = storyboard.instantiateViewControllerWithIdentifier("FileSelect") as! FileSelect controller.path = paths[indexPath.row] self.presentViewController(controller, animated: true, completion: nil) } func refreshPaths() { paths = manager.subpathsAtPath(fullPath) print("fullPath = \(fullPath)") if paths != nil { print("paths.count = \(paths.count)") } } override func viewWillAppear(animated: Bool) { refreshPaths() self.myTableView.reloadData() } override func viewDidLoad() { super.viewDidLoad() myTableView.delegate = self myTableView.dataSource = self manager = NSFileManager.defaultManager() fullPath = NSHomeDirectory() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
FileAdd.swiftに追加するコード(赤字部分) |
import UIKit class FileAdd: UIViewController { @IBOutlet weak var myTextField: UITextField! @IBOutlet weak var myTextView: UITextView! @IBAction func tapCancel(sender: AnyObject) { dismissViewControllerAnimated(true, completion: nil) } @IBAction func tapAdd(sender: AnyObject) { var path:String = myTextField.text ?? "" if path.hasPrefix("/") { path = path.substringFromIndex(path.startIndex.successor()) } path = NSHomeDirectory() + "/" + path let contents: String = myTextView.text ?? "" do { try contents.writeToFile(path, atomically:true, encoding:NSUTF8StringEncoding) } catch let error as NSError { let alert: UIAlertController = UIAlertController(title:"Add File", message: "error occurred: "+String(error),preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) return; } dismissViewControllerAnimated(true, completion: nil) } @IBAction func tapMkdir(sender: AnyObject) { var path:String = myTextField.text ?? "" if path.hasPrefix("/") { path = path.substringFromIndex(path.startIndex.successor()) } path = NSHomeDirectory() + "/" + path do { try NSFileManager.defaultManager().createDirectoryAtPath(path,withIntermediateDirectories:true, attributes: nil) } catch let error as NSError { let alert: UIAlertController = UIAlertController(title:"Make Dir", message: "error occurred: "+String(error),preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) return; } dismissViewControllerAnimated(true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
FileSelect.swiftに追加するコード(赤字部分) |
import UIKit class FileSelect: UIViewController { var path: String! // this value should be set from the outer var fullPath: String! @IBOutlet weak var myLabel: UILabel! @IBOutlet weak var myTextView: UITextView! @IBAction func tapBack(sender: AnyObject) { dismissViewControllerAnimated(true, completion: nil) } @IBAction func tapRemove(sender: AnyObject) { do { try NSFileManager.defaultManager().removeItemAtPath(fullPath) dismissViewControllerAnimated(true, completion: nil) } catch let error as NSError { let alert: UIAlertController = UIAlertController(title:"Selected File", message: "error occurred: "+String(error), preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) } } func fileContents() { let manager:NSFileManager = NSFileManager.defaultManager() var isDir: ObjCBool = false let flag = manager.fileExistsAtPath(fullPath, isDirectory:&isDir) if flag && Bool(isDir) { myTextView.text = "[[Directory]]" } else if flag { if fullPath.hasSuffix(".txt") { do { myTextView.text = try NSString(contentsOfFile: fullPath, encoding: NSUTF8StringEncoding) as String } catch let error as NSError { let alert: UIAlertController = UIAlertController(title:"Selected File", message: "cannot read .txt file: "+String(error), preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) } } else { myTextView.text = "[[not directory, but has no \".txt\" suffix]]" } } else { let alert: UIAlertController = UIAlertController(title:"Selected File", message: "No such file exists", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) } } func setup() { if path == nil { let alert: UIAlertController = UIAlertController(title:"Selected File", message: "path is nil: ", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title:"Cancel",style:UIAlertActionStyle.Cancel,handler:nil)) presentViewController(alert,animated:true, completion:nil) path = "" } fullPath = NSHomeDirectory() + "/" + path myLabel.text = path } override func viewDidAppear(animated: Bool) { setup() fileContents() } override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
まず最初の画面で "List Files"ボタンと "Add File" ボタンが表示される。 "List Files"ボタンを押すと、ファイルの一覧が表示される。 アプリ毎にiOS上のファイル・システムの一部が割り当てられており、以下のような方針でファイルを配置する。
List Filesボタン --> |
Backボタン --> 最初の画面へ |
最初の画面で"Add File" ボタンをタップすると、FileAddクラスの画面となる。 Pathを指定して"Make Dir"ボタンをタップするとそのパスに沿ってフォルダが生成される。
Add Fileボタン --> |
Make Dirボタン --> フォルダ生成。 最初の画面へ |
List Filesボタン --> 生成を確認。 |
Backボタン --> 最初の画面へ |
最初の画面で"Add File" ボタンをタップすると、FileAddクラスの画面となる。 Pathを指定して、"Add File" ボタンをタップするとファイルが生成され、ファイルの内容はText View中に記述した文字列となる。
Add Fileボタン --> | Add Fileボタン --> ファイルが生成される |
List Filesボタン --> 生成を確認。 |
項目をタップ --> c.txtの詳細 |
簡単のため、 フォルダの詳細を表示した場合は、ファイルの内容は"[[Directory]]" とだけ表示する。 また、フォルダでない通常のファイルでも拡張子が".txt"でない場合は "[[not directory, but has no ".txt" suffix]]" と表示する。
ファイルの詳細を表示中に "Remove" ボタンをタップすると、そのファイルやフォルダを消すことができる。 フォルダの中に他のファイルやフォルダが存在しても丸ごと消せるので注意すること。