• 締切済み

Swiftについて教えてください

前回PHAssetからNSDataへの変換のしかたを質問させていただき、回答をいただきました。それを参考にいろいろ調べてみたのですが、勉強不足で解決できませんでした。 requestImageDataForAssetを使いPHAssetから直接NSDataを作れることは分かったのですが、具体的な使い方が分からず、投稿させていただきました。 前回の質問で回答をいただいた func requestImageDataForAsset(_ asset: PHAsset, options options: PHImageRequestOptions?, resultHandler resultHandler: (NSData?, String?, UIImageOrientation, [NSObject : AnyObject]?) -> Void) -> PHImageRequestID これが理解できずにいます。 aseetという配列の中にPHAssetが入っており、1つずつPHAssetを取り出し、NSDataに変換し、nsdataという配列に格納していきたいと考えています。 requestImageDataForAssetを使って上記のようなことをするにはどのようにしたらよいのか教えてください。

  • dkong
  • お礼率86% (170/197)
  • Swift
  • 回答数3
  • ありがとう数2

みんなの回答

回答No.3

No.2の補足の質問について回答します。 > 後置クロージャを普通にしたら > { > image, info in > //ここでUIImageを取得します。 > self.photoImageView.image = image > print("UIImage get!"); > } > は、下記と同じということでいいのでしょうか? > resultHandler:{(image,info)->Void in > //ここでUIImageを取得します。 > self.photoImageView.image = image > print("UIImage get!"); > }) > resultHandlerは書く必要はないのでしょうか? 同じです。 resultHandlerは書く必要ありません。 安易に質問しないで、疑問に思うなら実際に両方のコーディングを 自分で動かして試してみてください。それでもし同じでないと思う状況を見つけたのなら その具体例を説明して質問してください。 > image, infoがどこと関係してるのかがよく分かりません。 > imageはUIImageを定義しておくのでしょうか? > infoは何を意味していますか? クロージャの引数は、AppleのリファレンスのrequestImageForAssetの説明にある通り resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) と定義されていて、 第1パラメータはUIImage(のオプショナル型)で、 第2パラメータは[NSObject : AnyObject]というDictionary(のオプショナル型)です。 参考サイトのサンプルでは、それにそれぞれimage、infoという名前をつけて受け取っているだけです。(名前は別にimageやinfoじゃなくてもかまいません。参考サイトのサンプルではわかりやすいからそういう名前にしているだけです。) infoで受け取る内容は、これもAppleのリファレンスにある通り 「A dictionary providing information about the status of the request. See Image Result Info Keys for possible keys and values.」 リクエストの状態についての情報を提供するDictionaryです。 取り得るキーと値については「Image Result Info Keys」を参照してくださいとあるので、 その青いリンクをクリックして https://developer.apple.com/library/ios/documentation/Photos/Reference/PHImageManager_Class/#//apple_ref/doc/constant_group/Image_Result_Info_Keys を参照すれば、そこに詳しく説明されています。 このあたりもピンと来なければ、安易に質問する前に サンプルで示されたものを動かして、実際に受け取ったinfoの値を printで出力して確認する等、自分で調べる癖をつければ、 実際のイメージがわき、自分で理解できるようになってくるはずです。

回答No.2

No.1です。 > この部分はどういう意味ですか? これはimageを取得した時に呼び出されるクロージャの呼び出しパラメータ形式を表しています。 > 戻り値のPHImageRequestIDはどんな値なのでしょうか? 参考にしているAppleのリファレンスサイトで、その「->PHImageRequestID」 と描かれている青い文字をクリックしたら、 https://developer.apple.com/library/ios/documentation/Photos/Reference/PHImageManager_Class/#//apple_ref/swift/tdef/c:@T@PHImageRequestID に移動すると思います。 そこに書かれている通り、イメージ取得要求に対応するIDで、 もし途中でイメージ取得をキャンセルしたくなった時に、 そのIDを使って、どの取得要求をキャンセルするのか指定するのに使います。 > 教えていただいたサイトの以下の部分にないのですが必要ではないのでしょうか? これは、Trailing Closure(後置クロージャ)と呼ばれるswift独特の書き方で、 最終パラメータにクロージャを記述する場合、通常は、最終パラメータ記述位置に{~}でクロージャを書いて、 最後にメソッドパラメータの終了を意味する閉じかっこ「)」を入れますが、これだと、最後の閉じかっこが「})」の ようになってややこしくなるので、最終パラメータでクロージャを記述する場合に限って、 先に閉じかっこ「)」を入れて関数パラメータの定義を終了させ、その直後に「{~}」を書くことで、 最終パラメータのクロージャを記述することができるようになっています。 一方、入力パラメータ形式通りにパラメータ内に記述するクロージャは、インラインクロージャと呼ばれます。 後置クロージャもインラインクロージャも書き方が違うだけで意味は同じです。 以下のサイトが参考になると思います。 http://swiftrithm.com/closures-trailing-closures/

dkong
質問者

お礼

丁寧な回答ありがとうございます。 クロージャがについて以前にも調べたことがあったのですが、理解しきれず、引数のなかで処理した値を使うってことかと思ってます。なの後置クロージャなどは全く理解できてませんでした。 追加の質問よろしくお願いします。

dkong
質問者

補足

後置クロージャを普通にしたら { image, info in //ここでUIImageを取得します。 self.photoImageView.image = image print("UIImage get!"); } は、下記と同じということでいいのでしょうか? resultHandler:{(image,info)->Void in //ここでUIImageを取得します。 self.photoImageView.image = image print("UIImage get!"); }) resultHandlerは書く必要はないのでしょうか? 引数 asset as! PHAsset targetSize: CGSize(width: 320, height: 320) contentMode: .AspectFill options: nil は理解できるのですが、 クロージャの引数のimage, infoがどこと関係してるのかがよく分かりません。 imageはUIImageを定義しておくのでしょうか? infoは何を意味していますか? 教えてください。よろしくお願いします。

回答No.1

前回の回答は、「requestImageForAssetでPHAssetからUIImageを作る方法を理解しているのであれば」という前提で回答しましたが、それを理解していないなら、 http://swift-salaryman.com/phasset.php とかを参考にして、まずはPHAssetからUIImageを取得する方法をマスターしてください。 それがマスターできれば、使い方は似たようなものです。

dkong
質問者

お礼

回答ありがとうございます requestImageForAssetでPHAssetからUIImageを取得する方法を十分理解できていませんでした。 今回教えていただいたサイトを参考にUIImageを取得することはできたのですが、appleのリファレンスとの違いを教えていただきたく補足コメントに質問させてください。

dkong
質問者

補足

リファレンスには requestImageForAsset(_ asset: PHAsset, targetSize targetSize: CGSize, contentMode contentMode: PHImageContentMode, options options: PHImageRequestOptions?, resultHandler resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) -> PHImageRequestID とあります。引数にある resultHandler resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) この部分はどういう意味ですか? 戻り値のPHImageRequestIDはどんな値なのでしょうか? 教えていただいたサイトの以下の部分にないのですが必要ではないのでしょうか? phimgr.requestImageForAsset(asset as! PHAsset, targetSize: CGSize(width: 320, height: 320), contentMode: .AspectFill, options: nil) { image, info in //ここでUIImageを取得します。 self.photoImageView.image = image print("UIImage get!"); } image, info inの部分の意味はどういう意味でしょうか?(クロージャー?) 教えてください。よろしくお願いします。分からないことが多くてすみません。

関連するQ&A

  • swift初心者で、計算機を作っています

    swiftで計算機を作っています。 しかし、エラーが出てしまいます nilを代入するのがいけないらしいことは分かったのですが、ではどうしたらよいのかいろいろ調べていろいろ行ったのですが(変数への代入をボタンの関数内したり、変数宣言をstring?にしたり、計算にnumberBox.textを直接キャストしたものを用いる、などなど)、どうしても治りません。 この記述をこう直せばいい、という回答をお願いします。 import UIKit class ViewController: UIViewController { @IBOutlet weak var result: UILabel! @IBOutlet weak var numberBox1: UITextField! @IBOutlet weak var numberBox2: UITextField! var num1:String = "" var num2 = 0 var num3:String = "" var num4 = 0 var res = 0 @IBOutlet weak var button1: UIButton! @IBAction func button1(sender: AnyObject) { add() } @IBOutlet weak var button2: UIButton! @IBAction func button2(sender: AnyObject) { sub() } @IBOutlet weak var button3: UIButton! @IBAction func button3(sender: AnyObject) { mul() } @IBOutlet weak var button4: UIButton! @IBAction func button4(sender: AnyObject) { div() } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. result.text = "計算結果" num1 = numberBox1.text! num2 = Int(num1)! num3 = numberBox2.text! num4 = Int(num3)! button1.setTitle("+", forState: .Normal) button2.setTitle("-", forState: .Normal) button3.setTitle("✖️", forState: .Normal) button4.setTitle("➗", forState: .Normal) } func add(){ res = num2 + num4 result.text = String(res) } func sub(){ res = num2 - num4 result.text = String(res) } func mul(){ res = num2 * num4 result.text = String(res) } func div(){ res = num2 / num4 result.text = String(res) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } エラーメッセージ fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) 回答をよろしくお願いします

    • ベストアンサー
    • Swift
  • Swiftについて教えてください

    下記のようにようにサーバにある画像を読み込んでいます。サーバのimgフォルダの中の画像( 1.png~20.png)を全て読み込み配列に入れる方法を質問して、回答をいただき解決しました。(以下のコード)それを拡張してサーバのimgフォルダの中の画像の数が分かってないものを配列に読み込もうとしています。画像の数が分かってないものを全て読み込み配列に入れる方法が分からず困っています。よろしくお願いします。 // URLリクエストを作る for i in 1...20 { let url = NSURL(string:"http://xxxxxxxxxxxxxxxx/img/"+String(i)+".png") let request = NSURLRequest(URL : url!) var error: NSError? // 同期通信を開始 if let resData:NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: &error){ let image = UIImage(data:resData) self.imageArray.append(image!) } }

  • swiftでOCRを利用したアプリを開発したいです

    http://blog.isana.net/2014/08/ios.html 上記サイトを参考にOCR機能を利用したプログラムを書いています しかし、objective-Cで記述されており、swiftへどう書き換えたら良いかわかりません 変換のサイトを使ってみたのですが、エラーが多発しており困っています。 以下のコードをどう書き換えたら良いでしょうか 回答をお願いします @IBAction func Camera(sender: AnyObject) { var imagePickerController: UIImagePickerController = UIImagePickerController() imagePickerController.setDelegate(self) imagePickerController.setAllowsEditing(true) if UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear) { imagePickerController.setSourceType(UIImagePickerControllerSourceTypeCamera) } else { imagePickerController.setSourceType(UIImagePickerControllerSourceTypeSavedPhotosAlbum) } presentViewController(imagePickerController, animated: true, completion: nil) } func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { self.selectedImage = info[UIImagePickerControllerEditedImage] imageView.setImage(selectedImage) dismissViewControllerAnimated(true, completion: nil) textView.setText(nil) var spinner: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyleGray) spinner.center = CGPointMake(160, 240) spinner.hidesWhenStopped = true view.addSubview(spinner) spinner.startAnimating() }

    • ベストアンサー
    • Swift
  • Swiftについて教えてください

    UICollectionviewに読み込んだ画像をタッチして枠線と番号を表示させようと下記のようにしてみたのですが、最後のセルにだけラベルの番号が表示されます。(枠を消したら数字も減ります)各セルにはラベルはきちんと配置されています。それをnumLabel.hidden = trueで消しておいて、セルをタッチした時にnumLabel.hidden = falseで表示させようとし考えています。なぜ最後のセルだけなのでしょうか。教えてください。よろしくお願いします。 import UIKit class ViewController: UIViewController ,UICollectionViewDataSource, UICollectionViewDelegate{ //画像を格納する配列 var imageArray:[UIImage] = [] //番号ラベル let numLabel: UILabel = UILabel(frame: CGRectMake(0,0,30,30)) //選択したIndexPath格納する配列 var selection: [NSIndexPath] = [] //コレクションビュー @ IBOutlet weak var imageCollection:UICollectionView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. //配列imageArrayに1~6.pngの画像データを格納 for i in 1...6{ imageArray.append(UIImage(named: "\(i).png")!) } } //コレクションビューのアイテム数を設定 func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { //戻り値にimageArrayの要素数を設定 return imageArray.count } //コレクションビューのセルを設定 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { //繰り返し使用することができるUICollectionViewCellのインスタンスを作成 var cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! UICollectionViewCell //セルのなかの画像を表示するImageViewのタグを指定 let imageView = cell.viewWithTag(1) as! UIImageView //セルの中のImage Viewに配列の中の画像データを表示 imageView.image = imageArray[indexPath.row]   //ラベルの設定 // 背景を青色にする. numLabel.backgroundColor = UIColor.blueColor() // 文字の色を白にする. numLabel.textColor = UIColor.whiteColor() //文字サイズ numLabel.font = UIFont.systemFontOfSize(12); // Textを中央寄せにする. numLabel.textAlignment = NSTextAlignment.Center //ラベルを非表示にする numLabel.hidden = true //セルにラベルを配置 cell.addSubview(numLabel) //設定したセルを戻り値にする return cell } //セルをタップしたとき func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { let cell = collectionView.cellForItemAtIndexPath(indexPath)! if let index = find(selection, indexPath) { selection.removeAtIndex(index) } else { selection.append(indexPath) } // 可視状態のセルを全て更新する collectionView.visibleCells().map({(cell: AnyObject) -> Void in self.updateCell(cell as! UICollectionViewCell) }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //セルの更新 func updateCell(cell: UICollectionViewCell) { if let indexPath = self.imageCollection?.indexPathForCell(cell){ if let index = find(selection, indexPath) { cell.contentView.layer.borderColor = UIColor.blueColor().CGColor cell.contentView.layer.borderWidth = 4.0 numLabel.hidden = false numLabel.text = "\(index+1)" } else { cell.contentView.layer.borderColor = UIColor.clearColor().CGColor cell.contentView.layer.borderWidth = 0.0 numLabel.hidden = true } } } }

    • ベストアンサー
    • Swift
  • swift データの保存、読み込みについて

    swiftのデータ保存と読み込みについて学習しています。 saveボタンを押すとテキストフィールドの文字が保存され、switchボタンを押すと保存された文字列が表示され、文字列が表示されている場合はその文字列を消去するプログラムを書いたのですが、実行してみるとデータ保存がうまくいっていないようでした。 どこに問題があるのでしょうか。回答をお願いします。 以下ソースコードです import UIKit class ViewController: UIViewController { @IBOutlet weak var word1: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func save1(sender: AnyObject) { let ud1a = NSUserDefaults.standardUserDefaults() ud1a.setObject(word1.text, forKey: "saveText1") } @IBAction func switch1(sender: AnyObject) { let ud1b = NSUserDefaults.standardUserDefaults() if(word1.text == nil){ var loadText1:String! = ud1b.stringForKey("saveText1") word1.text = loadText1 } else{ word1.text = nil } }

  • Swiftについて教えてください

    カメラロールにある写真をUICollectionViewCellに読み込んで表示させ、その写真をタッチしたときに、その写真のURL(保存されているカメラロールまでのパス?)を取得し、配列に格納しようと考えています。 「ALassetslibrary url 取得」というキーワードなどで調べてみたのですが、Objective-Cで書かれたものやimagePickerControllerを使ったもがほとんどでで、よくわかりませんでした。 http://tryworks-design.com/?p=2282 http://tech.camph.net/%E3%80%90ios%E3%80%91iphone%E3%81%AE%E3%82%AB%E3%83%A1%E3%83%A9%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8Bassetslibrary%E3%81%AB%E3%81%A4%E3%81%84/ ライブラリ内でのURL  [[asset defaultRepresentation] url] //AssetURL(NSURL*型) Swiftでの情報で http://qiita.com/BOPsemi/items/9a0338635647cd34c910 があったので、var library = ALAssetsLibrary()とし、 libraryのassetForURLというメソッドを使うのかなど調べてみたのですがよく分かりませんでした。 UICollectionViewCellに読み込んで表示させ、その写真をタッチしたときの func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { } の中でどのような処理をすれば良いのでしょうか?教えてください。よろしくお願いします。

    • ベストアンサー
    • Swift
  • C#で、引数における一次元と二次元配列の取り扱い

    C#について質問させていただきます。 以下のようにすればそれぞれ一次元配列と二次元配列を格納出来ますが 同時に一つの引数に収めることは無理なのでしょうか?    public static void Join(string[] Ary_str){ 本文 }    public static void Join(string[ , ] Ary_str){ 本文 } そのために、例えば以下のようにしたとします。    public static void Join(object Ary_obj){ 本文 } こうすれば一次元でも二次元でも格納出来ますが 格納された値が何次元配列なのか確認するために    Ary_obj.Rank としてもエラーになってしまいます。 (1)Objectに格納した値が何次元配列なのか確認する方法か (2)一次元でも二次元でも格納できる引数の指定方法 をご存じの方、ぜひお教え願います。><

  • swiftでOCRを利用したサンプルコードを書いて

    http://blog.isana.net/2014/08/ios.html 上記サイトを参考にobjective-Cをswiftに書き換えているのですが、どうしてもエラーが取れない場所があり、困っています。以下に記述するので、回答をお願いします。 import UIKit class ViewController: UIViewController,UIImagePickerControllerDelegate, UINavigationControllerDelegate { @IBOutlet weak var Textview: UITextView! @IBOutlet weak var Imageview: UIImageView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func Camera(sender: AnyObject) { var imagePickerController: UIImagePickerController = UIImagePickerController() //デリゲート指定 imagePickerController.delegate = self //トリミング指定 imagePickerController.allowsEditing = true //カメラの有無確認 if UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Rear){ //カメラ指定 imagePickerController.sourceType = .Camera } else { //アルバム指定 imagePickerController.sourceType = .SavedPhotosAlbum } //コントローラ起動 self.presentViewController(imagePickerController, animated: true, completion: nil) } func ImagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { /*ここから //イメージをメモリに保存 var selectedImage:UIImage self.selectedImage = info objectForKey:UIImagePickerControllerEditedImage //イメージビューに画像をセット self.Imageview.image = self.selectedImage ここ*/ //親ビューに戻る self.dismissViewControllerAnimated(true, completion: nil) //テキストを空に self.Textview.text = nil //インジケータ開始 var spinner: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) spinner.center = CGPointMake(160, 240) spinner.hidesWhenStopped = true view.addSubview(spinner) spinner.startAnimating() //OCR実行 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { var tesseract: Tesseract = Tesseract(language: "eng") tesseract.image = selectedImage tesseract.recognize() dispatch_async(dispatch_get_main_queue(), { self.Textview.text = tesseract.recognizedText spinner.stopAnimating() }) }) } } コメントアウトで示した部分の書き換えがどうしてもわからないです。 また、エラーが出てないだけでうまく動作がしないと思われる部分があれば、教えていただけると助かります。 回答宜しくお願いします。

  • 構造体の配列を関数に渡すには

    構造体の配列を関数の引数として渡そうとすると エラーになってしまいます ネットで調べてもいまいちわからなかったので ここで質問させてもらいます #include<stdio.h> struct A{   ・    ・    ・ }; void func(struct A *p); int main(void) { struct A x[3][4] = {     ・     ・     ・ }; func(x); return 0; } void func(struct A *p){     ・     ・    ・ } どうすれば渡すことができるのでしょうか? どなたか助言お願いします。

  • [VB.net] StringからByte配列への変換

    皆さんこんばんは。 最近VB.NET2000でVisual Basicをはじめたのですが、どうにもString型の値をByte配列へ変換するやり方が分かりません。 VB6.0だとByte配列にStringを代入するだけでいいそうなのですが、.NETで代入しようとすると『型"String"の値を"Byteの1次元配列"に変換できません』というビルドエラーが表れてしまいます。 CByte( Mid(str,i,1) ) CLng( Mid(str,i,1) ) 他にも上記コードのように一つずつ変換しようと試みたのですが、String中のある文字がワイドバイトらしく、System.InvalidCastExceptionが表れてしまいます。 ("『"を上下反転したような文字) ワイドバイトのStringを1バイトずつ区切ってByte配列やLong配列へ格納する手法というものはありませんでしょうか。 よろしくお願いします。

専門家に質問してみよう