執行效果
Text基礎設定
Text("PPPPPPPP OOOOOOOOOO IIIIIIIIII UUUUUUUUUU YYYYYYYYYY") //縮放最小的大小 .minimumScaleFactor(0.5) //最大兩行 .lineLimit(2) //allowsTightening設定成true的時,適應文本大小 //空間太小直接變... .allowsTightening(false) //多行皆以.center為對齊方式 .multilineTextAlignment(.center) .foregroundColor(Color.white) .padding(.leading, 10) .padding(.trailing, 10)
Text文字大小讀取
//1.繼承String新增方式 extension String { func widthOfString(usingFont font: UIFont) -> CGFloat { let fontAttributes = [NSAttributedString.Key.font: font] let size = self.size(withAttributes: fontAttributes) return size.width } func heightOfString(usingFont font: UIFont) -> CGFloat { let fontAttributes = [NSAttributedString.Key.font: font] let size = self.size(withAttributes: fontAttributes) return size.height } func sizeOfString(usingFont font: UIFont) -> CGSize { let fontAttributes = [NSAttributedString.Key.font: font] return self.size(withAttributes: fontAttributes) } } //2.讀取Text大小方式 let width: CGFloat = String("1234567890abc") .widthOfString(usingFont: UIFont.systemFont(ofSize: 18)) let height: CGFloat = String("1234567890abc") .heightOfString(usingFont: UIFont.systemFont(ofSize: 18)) let size: CGSize = String("1234567890abc") .sizeOfString(usingFont: UIFont.systemFont(ofSize: 18))
Text跑馬燈
struct paramModel { var animation: Int = 0 var textSize: CGFloat = 0 var opacity: Double = 1 var offsetXCurrent: CGFloat = 0 var offsetXMax: CGFloat = 0 } struct AMainView: View { @State var param = paramModel() let moveTime = 2.0//移動時間 let lastStopTime = 1.0//移動到最後,停止時間 let opacityTime = 0.1//停止後,隱藏文字動畫時間 let hideTime = 0.6//動畫結束後,至初始化等待時間 let firstStopTime = 1.0//初始化後,等待移動文字時間 func getFirstStopTime() -> DispatchTime { return DispatchTime.now()+firstStopTime } func getMoveAndStopTime() -> DispatchTime { return DispatchTime.now()+moveTime+lastStopTime } func getMoveToEndTime() -> DispatchTime { return DispatchTime.now()+moveTime+lastStopTime+hideTime+opacityTime } var body: some View { return GeometryReader { geometry in let maxSize = geometry.size.width//最大文字範圍(避免變...) let limitSize = geometry.size.width / 2//要顯示文字範圍 Group { Text("1234567890abcdefghiABCDEFGHIJKLMNOP") .foregroundColor(.red) .font(.system(size: 18)) .lineLimit(1) .allowsTightening(true) .background(ListenerView()) .onPreferenceChange(ViewSizeKey.self) { _ in param.textSize = CGFloat( String("1234567890abcdefghiABCDEFGHIJKLMNOP") .widthOfString(usingFont: UIFont.systemFont(ofSize: 18)) ) withAnimation(Animation.linear) { param.offsetXCurrent = limitSize-param.textSize param.offsetXMax = limitSize-param.textSize } } .offset(x: (param.animation != 0 && param.textSize != 0) ? param.offsetXCurrent : 0 , y: 0 ) .opacity(param.opacity) .animation( param.animation == 1 ? Animation.linear(duration: moveTime) : param.animation == 2 ? Animation.linear(duration: opacityTime) : nil ) .onAnimationDataChange(for: param.offsetXCurrent) { if param.offsetXMax == 0 { return } if param.offsetXCurrent == 0 { DispatchQueue.main.asyncAfter( deadline: getFirstStopTime(), execute: { withAnimation(Animation.default, { param.offsetXCurrent = param.offsetXMax }) }) } else if param.offsetXCurrent != 0 { param.animation = 1 DispatchQueue.main.asyncAfter( deadline: getMoveAndStopTime(), execute: { param.animation = 2 param.opacity = 0 }) DispatchQueue.main.asyncAfter( deadline: getMoveToEndTime(), execute: { param.animation = 0 withAnimation(Animation.default, { param.offsetXCurrent = 0 }) param.opacity = 1 }) } } .frame(width: maxSize, alignment: .leading)//這不設定,過長文字會變成... }.frame(width: limitSize, alignment: .leading) .mask ( HStack(spacing: 0) { LinearGradient( gradient: Gradient( colors: [Color.black, Color.black] ), startPoint: .leading, endPoint: .trailing ) } ).frame(width: limitSize) } } }
訂閱Codeilin的旅程,若有最新消息會通知。
廣告
發表迴響