lineLimitでテキストの行数に制限をかけつつ、一定数を超えた時に「もっと見る」を表示し、「もっと見る」をタップすると全文表示される……そんなものを作りたくて調べて作りましたよ

大枠の流れ

流れとしては、

1. lineLimitを設定する
2. テキストが、その行数を超えるかチェックする
3. 超えてると判断したら、もっと見る を表示するフラグをtrueにする
4. もっと見る を押すと、もっと見る ボタンを消しながら、lineLimitを無効にする

こんな感じらしい

以下コード

struct PostCardText: View {
    let TextData:String
    
    @State var LineLimit = 3  /// 3行まで許可。これを超えると「もっと見る」ボタンが出て残り省略
    
    @State var moreText:Bool = false  ///全文表示されてるかどうかのフラグ
    @State var canBeExpanded = false //「もっと見る」を表示するかどうかのフラグ
    
    init(TextString:String?){
        ////niの場合は空白にするため
        if let Textdata = TextString{
            self.TextData = Textdata
        }else{
            self.TextData = ""
        }
    }
    
    var body: some View {
        VStack{
            Text(TextData.trimmingCharacters(in: .whitespacesAndNewlines))
                .lineLimit(moreText ? nil : LineLimit)
                .background(
                    ViewThatFits(in: .vertical){
                        /// lineLimitで制限された領域とlineLimitなしの領域が同じ場合は、hidden、
                        /// 大きさを超えてる場合は、無色の背景色を表示しつつ、
                        /// 「もっと見る」表示フラグをtrueにする

                        Text(TextData.trimmingCharacters(in: .whitespacesAndNewlines))
                            .hidden()
                        
                        Color.clear
                            .onAppear{
                                canBeExpanded = true
                            }   
                    }
                )//background
                .truncationMode(.tail)
            
            
            if canBeExpanded == true{
                Text(moreText ? "" : "もっと見る")
                    .onTapGesture{
                        // もっと見る を押すと、省略を解除する
                        moreText = true
                    }
            }

        }///Vstack

    }

}

ViewThatFits の使い方は色々応用が効きそうですね。

同じカテゴリの記事

コメント