48224


MessageKitのGitHubにあるソースコードで  
MessageInputBarDelegateプロトコル内に記述されている

messagesCollectionView.insertSections([messageList.count - 1])

の意味がよく分かりません。  
このコードでsendボタンを押すとメッサージが表示されるようになるのは分かるのですが、  
[messageList.count-1]とは何を意味するのでしょうか。

[code]

    extension ConversationViewController: MessageInputBarDelegate {
    
    func messageInputBar(_ inputBar: MessageInputBar, didPressSendButtonWith text: String) {
    
        // Each NSTextAttachment that contains an image will count as one empty character in the text: String
    
        for component in inputBar.inputTextView.components {
    
            if let image = component as? UIImage {
    
                let imageMessage = MockMessage(image: image, sender: currentSender(), messageId: UUID().uuidString, date: Date())
                messageList.append(imageMessage)
                messagesCollectionView.insertSections([messageList.count - 1])
    
            } else if let text = component as? String {
    
                let attributedText = NSAttributedString(string: text, attributes: [.font: UIFont.systemFont(ofSize: 15), .foregroundColor: UIColor.blue])
    
                let message = MockMessage(attributedText: attributedText, sender: currentSender(), messageId: UUID().uuidString, date: Date())
                messageList.append(message)
                messagesCollectionView.insertSections([messageList.count - 1])
            }
    
        }
    
        inputBar.inputTextView.text = String()
        messagesCollectionView.scrollToBottom()
    }
    
[/code]

}


CC BY-SA 4.0
2018-09-08T16:31:14.047
48223
2018-09-08T19:32:55.707
27271
question
swift ios xcode
Swift のライブラリ MessageKitについて


こちら、MessageKitが`UICollectionView`をどのように表示に利用しているかまでわかればもう少しわかりやすく書けるのかもしれませんが、そこら辺まではわからないので、取り敢えず文法的な説明だけ。

少し長くなってしまいましたので、ざっと斜め読みして、「そんなことはもうわかってるよ!」って部分はうまく読み飛ばして下さい。

* * *

まず、該当のメソッドですが、MessageKitに特有のものではなく`UICollectionView`のメソッドです。(正確に言うと`messagesCollectionView`の型は`MessagesCollectionView`で、`MessagesCollectionView`が`UICollectionView`から継承したメソッド、ってことになります。)

##
[`insertSections(_:)`](https://developer.apple.com/documentation/uikit/uicollectionview/1618090-insertsections)

で、このメソッドがどう言う場面で使われてどう言う意味を持つのかは、英語がさくさく読める方でも、わかるようには書かれていません…。

この辺はあなたがどれだけ`UICollectionView`(や`UITableView`)を使ったことがあるかで理解しやすさが変わってくるのですが、それらのdataSourceとして使われているデータモデルが更新された場合、そのことを`UICollectionView`に正しく伝えてやらないと、ユーザの見ている表示が正しく更新されません。

データモデル全体を更新した場合には、`reloadData()`なんてものを呼ぶのですが、これだと画面全体が更新されてしまうので、重い上に、「1項目追加」なんて場合でも画面全体が一挙に更新されてしまい、どこに項目が追加されたのかがわかるようには表示してくれません。

そこで、`UICollectionView`には「項目の追加」「項目の移動」「項目の削除」「セクションの追加」「セクションの移動」「セクションの削除」と行ったありがちなデータモデルの更新を`UICollectionView`に知らせるメソッドが用意されています。

`insertSections(_:)`メソッドはそのうちの「セクションの追加」を知らせる(⇨知らせられた`UICollectionView`はセクション追加のアニメーションを使って新しいセクションを表示してくれる)と言うメソッドです。

* * *

同じサンプルコードの中に次のようなメソッドが定義されているのがわかるでしょうか。(`extension
ConversationViewController: MessagesDataSource`の中。)

[code]

    func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
        return messageList.count
    }
    
[/code]

セクション数を返すべきメソッドで、`messageList`の要素数をそのまま返しています。つまり`ConversationViewController`では、`messageList`の各要素がそれぞれ1セクションに対応していることがわかります。

* * *

で、ここまで理解できれば、あなたがご質問になった行は前の行と強い結びつきがあることがわかります。

[code]

            messageList.append(imageMessage)
            messagesCollectionView.insertSections([messageList.count - 1])
    
[/code]

(2箇所ありますが、もう一方も考え方は同じ。)

1行目の`messageList.append(...)`で「(セクションを表す)データモデルの最後に1要素追加」しているので、2行目で「セクションが最後に追加されたよ」と言うのを`messagesCollectionView`に伝えているわけです。

* * *

文法的な部分をもう少し解説しておくと、引数の`[messageList.count - 1]`の両端の`[`
`]`は配列リテラルを表していて、その中身は`messageList.count - 1`の1要素のみです。`〜.count -
1`と言うのは配列の最後の要素のインデックスを表しているのはお分かりでしょう。

`messageList`はセクションを表しているのですから、その最後の要素のインデックスは、つまり新しく追加されたセクションのセクション番号でもあります。

`insertSections(_:)`は複数のセクションが一括で追加された時にも使えるので、引数を`IndexSet`と言うインデックス専門の集合型で受け取るのですが、上記の配列リテラルは、この`IndexSet`型に変換されて、`insertSections(_:)`に渡されます。

* * *

つまり`messagesCollectionView.insertSections([messageList.count - 1])`は、

### 「最後にセクションを1個追加した(ので画面も更新してほしい)」

ことを`messagesCollectionView`に伝えています。

`messagesCollectionView`では1セクションが1メッセージですから、画面に新しいメッセージが追加される形で画面が更新されることになります。


CC BY-SA 4.0
2018-09-08T19:32:55.707
48224
2018-09-08T19:32:55.707
2020-06-17T08:14:45.997
-1
13972
48223
answer