簡體   English   中英

SwiftUI - 自動滾動水平滾動視圖以顯示全文 label

[英]SwiftUI - Autoscroll horizontal scrollview to show full text label

我有以下代碼可以完美運行。 但是如果在滾動視圖中特別可見Titles並且用戶單擊可見的文本部分時,我無法解決的一個問題,我不僅想要選擇我想要的標題將 scollview 設置為“自動滾動”,以便完整標題顯示在滾動視圖中,而僅顯示部分文本。

import SwiftUI

struct CustomSegmentedPickerView: View {

  @State private var selectedIndex = 0
  private var titles = ["Round Trip", "One Way", "Multi-City", "Other"]
  private var colors = [Color.red, Color.green, Color.blue, Color.yellow]
  @State private var frames = Array<CGRect>(repeating: .zero, count: 4)

  var body: some View {

    VStack {

      ScrollView(.horizontal, showsIndicators: false) {

          ZStack {

            HStack(spacing: 10) {

              ForEach(self.titles.indices, id: \.self) { index in

                Button(action: { self.selectedIndex = index }) {

                    Text(self.titles[index])

                }.padding(EdgeInsets(top: 16, leading: 20, bottom: 16, trailing: 20)).background(

                  GeometryReader { geo in

                    Color.clear.onAppear { self.setFrame(index: index, frame: geo.frame(in: .global)) }

                 })

             }

          }
          .background(

              Capsule().fill(self.colors[self.selectedIndex].opacity(0.4))
                  .frame(width: self.frames[self.selectedIndex].width,
                   height: self.frames[self.selectedIndex].height, alignment: .topLeading)
                  .offset(x: self.frames[self.selectedIndex].minX - self.frames[0].minX)
          , alignment: .leading

            )

         }
         .animation(.default)
         .background(Capsule().stroke(Color.gray, lineWidth: 3))

         Picker(selection: self.$selectedIndex, label: Text("What is your favorite color?")) {

            ForEach(0..<self.titles.count) { index in

              Text(self.titles[index]).tag(index)

            }

          }.pickerStyle(SegmentedPickerStyle())

          Text("Value: \(self.titles[self.selectedIndex])")
          Spacer()

       }

    }

  }

  func setFrame(index: Int, frame: CGRect) {

    self.frames[index] = frame

  }

}


struct CustomSegmentedPickerView_Previews: PreviewProvider {

    static var previews: some View {

        CustomSegmentedPickerView()

    }

}

嘗試這個:

struct ScrollText: View
{
    @State var scrollText: Bool = false

    var body: some View
    {
        let textWidth: CGFloat = 460
        let titleWidth: CGFloat = 240.0
        let titleHeight: CGFloat = 70.0

        HStack
        {
            ScrollView(.horizontal)
            {
                Text("13. This is my very long text title for a tv show")
                    .frame(minWidth: titleWidth, minHeight: titleHeight, alignment: .center)
                    .offset(x: (titleWidth < textWidth) ? (scrollText ? (textWidth * -1) - (titleWidth / 2) : titleWidth ) : 0, y: 0)
                    .animation(Animation.linear(duration: 10).repeatForever(autoreverses: false), value: scrollText)
                    .onAppear {
                        self.scrollText.toggle()
                    }
            }
        }
        .frame(maxWidth: titleWidth, alignment: .center)
    }
}

可選的:

如果您想計算文本寬度(而不是使用常量),那么您可以使用 GeometryReader(實時讀取渲染對象的實際尺寸)

或者你可以使用 UIKit 來計算寬度(我使用這種方法,它非常依賴並且可以在渲染發生之前實現計算)

將此擴展添加到您的代碼中:

// 字符串+sizeUsingFont.swift

import Foundation
import UIKit
import SwiftUI

extension String
{
    func sizeUsingFont(fontSize: CGFloat, weight: Font.Weight) -> CGSize
    {
        var uiFontWeight = UIFont.Weight.regular
        
        switch weight {
        case Font.Weight.heavy:
            uiFontWeight = UIFont.Weight.heavy
        case Font.Weight.bold:
            uiFontWeight = UIFont.Weight.bold
        case Font.Weight.light:
            uiFontWeight = UIFont.Weight.light
        case Font.Weight.medium:
            uiFontWeight = UIFont.Weight.medium
        case Font.Weight.semibold:
            uiFontWeight = UIFont.Weight.semibold
        case Font.Weight.thin:
            uiFontWeight = UIFont.Weight.thin
        case Font.Weight.ultraLight:
            uiFontWeight = UIFont.Weight.ultraLight
        case Font.Weight.black:
            uiFontWeight = UIFont.Weight.black
        default:
            uiFontWeight = UIFont.Weight.regular
        }
        
        let font = UIFont.systemFont(ofSize: fontSize, weight: uiFontWeight)
        let fontAttributes = [NSAttributedString.Key.font: font]
        return self.size(withAttributes: fontAttributes)
    }
}

並像這樣使用它:

let textWidth: CGFloat = "13. This is my very long text title for a tv show".sizeUsingFont(fontSize: 24, weight: Font.Weight.regular).width

當然將文本放在 var 中並更改字體大小和粗細以滿足您的需求

另外,如果您要在按鈕的 label中使用此解決方案,我建議將onAppear()代碼放在異步調用中,請參閱此答案:

aheze 現場回答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM