【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る！【画像リスト化編】

# **目次**
- 前回
- 投稿した画像をリストにして、表示させる
- 感想
- 次回

# **前回**
[【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る！【写真投稿編】](https://qiita.com/umagoro/items/3e86c0aa9306775d5731)

# **投稿した画像をリストにして、表示させる**
今回は、投稿した画像をリスト化にして、表示させようと思う。
まずは、完成イメージから。
### **①完成イメージ**
![インスタサンプル3.gif](https://qiita-image-store.s3.amazonaws.com/0/154610/7a223649-642c-2ae6-cc5c-5cf9e1572b80.gif)

### **②技術的な話**
まず、今回の制作のポイントは**UIImageViewを配列に入れる事が出来るか？**という事だ。

通常のArrayでは出来ないが、以下のコードであれば可能になる。

```swift
var ImgArray = [UIImageView](repeating: UIImageView(), count: 6)
```

これで、変数ImgArrayに6個のUIImageViewが要素に格納することができる。

続いて、画像のリストについてだが、今回の制作では最新の投稿順に並べたいので、
あらかじめ、カウントダウン値を設定して、for-in文でカウントアップさせると同時に、カウントダウン値をカウントダウンしていくようにした。




```swift
var CountDown = CountValue
var ImgArray = [UIImageView](repeating: UIImageView(), count: CountValue + 1)
    //ダウンロードURLの存在確認
    if CountValue != 0 {
       for i in 1 ... CountValue {
           let imageURL = self.ref.child("images/\(user.uid)/\(CountDown)/profile")
           ImgArray[i] = UIImageView(frame: CGRect(x: (w2 - 200) / 2, y: CGFloat(newY), width: 200, height: 200))
            print(newY)
            print(imageURL)
            imageURL.observe(DataEventType.value, with: { (snapshot) in
            let url = snapshot.value as? String
            //ダウンロードURLを取得し、ImageViewに反映
            let strURL = URL(string: url!)
            ImgArray[i].sd_setImage(with: strURL)
            scView.addSubview(ImgArray[i])
           })
           newY += 220
           scView.contentSize = CGSize(width: 0, height: newY)
            CountDown -= 1
       }
       newY = 100
   }
                    
   self.view.addSubview(scView)
```

そして、カウントダウン値を使って、以下の行のようにすれば、画像が降下順になる。

```swift
let imageURL = self.ref.child("images/\(user.uid)/\(CountDown)/profile")
```


また今回は、画像表示にUIScrollViewを使用している。

```swift
let scView = UIScrollView(frame: CGRect(x: 0 , y: 200, width: w2, height: h2 - 300))
    scView.isPagingEnabled = false
    scView.backgroundColor = .white
```

最後のscView.backgroundColorだが、これは画像をアップロードした際に過去の画像データがUIScrollViewの方に残ってしまうため、一旦、背景を白色にしている。


### **③コード**
最終的なコードがこちら。

```swift:ImageAddViewController.swift
import UIKit
import Firebase
import SDWebImage

//ディスプレイサイズ取得
let w2 = UIScreen.main.bounds.size.width
let h2 = UIScreen.main.bounds.size.height

//カウント設定
var count: String!

//UIScrollViewの高さ初期値
var newY = 100


class ImageAddViewController: UIViewController {
    //DB参照作成
    var ref: DatabaseReference!
    //ユーザーUID取得
    let userID = Auth.auth().currentUser?.uid
    //アップロードボタン
    let add = UIButton(frame: CGRect(x: (w2 - 150) / 2, y: 150, width: 150, height: 30))
    override func viewDidLoad() {
        //DBインスタンス作成
        ref = Database.database().reference()
        super.viewDidLoad()
        
        
        //アップロードボタン設定
        add.backgroundColor = .red
        add.addTarget(self, action: #selector(ImageAddViewController.Imageadd(_:)), for: .touchUpInside)
        add.setTitle("アップロード", for: UIControlState())
        view.addSubview(add)
        
        //ダウンロードURL取得して、Storageからダウンロードする
        //ログイン情報取得
        let user = Auth.auth().currentUser
        if let user = user {
            
            //imgcountのカウントデータ値の存在確認
            let imgCount = self.ref.child("imgcount/\(user.uid)/count")
            imgCount.observe(DataEventType.value, with: { (snapshot) in
                let Count = snapshot.value
                var Countstr = Count as? String
                if Countstr == nil {
                    //存在しない場合、新規データ作成(countは0にする)
                    self.ref.child("imgcount").child(self.userID!).setValue(["count": "0"])
                    Countstr = "0"
                } else {
                    //UIScrollView初期設定
                    let scView = UIScrollView(frame: CGRect(x: 0 , y: 200, width: w2, height: h2 - 300))
                    scView.isPagingEnabled = false
                    scView.backgroundColor = .white
                    //データから呼んだ値を、各変数にセットする
                    var CountInt = Int(Countstr!) //数値化
                    var CountValue = CountInt!   //強制アンラップ
                    var CountUp = CountValue + 1  //カウントアップ
                    //カウンタの初期設定
                    let ud = UserDefaults.standard
                    ud.set(CountUp, forKey: "count")
                    //カウントダウン値
                    var CountDown = CountValue
                    //画像表示用UIImageView
                    var ImgArray = [UIImageView](repeating: UIImageView(), count: CountValue + 1)
                    //ダウンロードURLの存在確認
                    if CountValue != 0 {
                        for i in 1 ... CountValue {
                            //ダウンロードURL取得
                            let imageURL = self.ref.child("images/\(user.uid)/\(CountDown)/profile")
                            ImgArray[i] = UIImageView(frame: CGRect(x: (w2 - 200) / 2, y: CGFloat(newY), width: 200, height: 200))
                            print(newY)
                            print(imageURL)
                            imageURL.observe(DataEventType.value, with: { (snapshot) in
                                let url = snapshot.value as? String
                                //ダウンロードURLを取得し、ImageViewに反映
                                let strURL = URL(string: url!)
                                //画像を配列に保存
                                ImgArray[i].sd_setImage(with: strURL)
                                scView.addSubview(ImgArray[i])
                            })
                            //高さを220延ばす
                            newY += 220
                            scView.contentSize = CGSize(width: 0, height: newY)
                            //カウントダウン
                            CountDown -= 1
                        }
                        
                        //処理後、初期値に戻す
                        newY = 100
                    }
                    
                    self.view.addSubview(scView)
                }
                //imagesのデータの存在確認
                let newUser = self.ref.child("images/\(user.uid)/\(Countstr!)/profile")
                newUser.observe(DataEventType.value, with: { (snapshot) in
                    let profile = snapshot.value as? String
                    if profile == nil  {
                        //データ値がない場合、新規データを作成
                        self.ref = Database.database().reference()
                        self.ref.child("images").updateChildValues(["\(self.userID!)": "userID"])
                        print("新規ユーザー")
                    } else {
                        print("既存")
                    }
                    
                })
            })
        }
                
            
        
        
    }
    
    ///アルバム呼び出し
    @objc func Imageadd(_ : UIButton) {
        pickImageFromLibrary()
    }

    //カウンタ
    func countPhoto() -> String {
        let ud = UserDefaults.standard
        let count = ud.object(forKey: "count") as! Int
        ud.set(count + 1, forKey: "count")
        return String(count)
    }

}

//アルバムにアクセス
extension ImageAddViewController: UINavigationControllerDelegate {
    func pickImageFromLibrary() {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
            let controller = UIImagePickerController()
            controller.delegate = self
            controller.sourceType = UIImagePickerControllerSourceType.photoLibrary
            
            present(controller, animated: true, completion: nil)
        }
    }
}

//Storageに書き込み
extension ImageAddViewController: UIImagePickerControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo
        info: [String : Any]) {
        let storage = Storage.storage()
        let storageRef = storage.reference()
        let user = Auth.auth().currentUser
        if let user = user {
            count = countPhoto()
            if let data = UIImagePNGRepresentation(info[UIImagePickerControllerOriginalImage] as! UIImage) {
                let reference = storageRef.child("image/" + user.uid + "/" + count + ".jpeg")
                let meta = StorageMetadata()
                meta.contentType = "image/jpeg"
                reference.putData(data, metadata: meta, completion: { metaData, error in
                    if (error != nil) {
                        print("Uh-oh, an error occurred!")
                    } else {
                        //URL型をNSstring型に変更
                        let downloadURL = metaData!.downloadURL()
                        
                        let data = downloadURL!.absoluteString
                        self.ref = Database.database().reference()
                        self.ref.child("images").child(self.userID!).child(count).updateChildValues(["profile": data])
                        self.ref.child("imgcount").child(self.userID!).setValue(["count": count])
                        print("成功！")
                    }
                })
                dismiss(animated: true, completion: nil)
            }
        }
    }
        
}

```

### **④ 完成**
![インスタサンプル3.gif](https://qiita-image-store.s3.amazonaws.com/0/154610/bd6bc648-30cf-9221-bdb1-09e19bfa10f8.gif)


#  **感想**
画像リスト化は大変でしたが、色々知らないこともあって、非常に勉強になりました。
~~次回のテーマはまだ未定ですが、プロフィール関連のページを作ろうかなと思います。~~


# 次回
[【iOS】プログラミング素人の俺が、Swift + Firebaseを使って、インスタクローンを作る！【ユーザページ完成編①】](https://qiita.com/umagoro/items/a00ba729e5bb350c4f3c)