SwiftUI -类似TikTok的评论表

jvlzgdj9  于 5个月前  发布在  Swift
关注(0)|答案(2)|浏览(50)

我想创建一个TikTok评论克隆,意思是:

  • 背景内容应保持不变
  • 工作表应从底部滑动
  • 底部应有注解框
  • 点击注解框应打开键盘,注解框应向上滑动

运行下面的代码,点击蓝色方块激活评论。你会看到红色背景如何滑动到顶部

import SwiftUI

struct TikTokView: View {
  
  @State var isPresented: Bool = false
  
  var body: some View {
    ZStack {
      Color.red
      
      VStack {
        RoundedRectangle(cornerRadius: 15)
          .fill(Color.blue)
          .frame(width: 50, height: 50)
          .onTapGesture {
            isPresented.toggle()
          }
      }
      .ignoresSafeArea(.keyboard)
      CommentsSheetView(isPresented: $isPresented)
    }
  }
}

struct CommentsSheetView: View {
  
  @Binding var isPresented: Bool
  @State private var text: String = ""
  
  var transition: AnyTransition = .move(edge: .bottom)
  
  var body: some View {
    ZStack {
      if isPresented {
        Color.black.opacity(0.5).ignoresSafeArea()
        
        VStack {
          Spacer()
          ScrollView(.vertical, content: {
            VStack {
              
              ForEach(0...50, id: \.self) { i in
                Text("Comment").foregroundStyle(.pink)
                Spacer()
              }
            }
            .frame(maxWidth: .infinity)
          })
          .frame(height: (550 - 80))
          .frame(maxWidth: .infinity)
          .padding(.bottom, 80)
          .background(.white.opacity(0.1))
        }
        .ignoresSafeArea(.keyboard)
        .fixedSize()
        .transition(transition)
        
        VStack {
          Spacer()
          HStack {
            Text("LOREM")
            
            TextField("TESTING", text: $text, axis: .vertical)
              .keyboardType(.asciiCapable)
              .autocorrectionDisabled(true)
              .foregroundStyle(.pink)
          }
          .frame(minHeight: 50, maxHeight: 100)
          .background(.green.opacity(0.1 ))
        }
        .frame(maxWidth: .infinity)
        .transition(transition)
      }
    }
  }
}

#Preview {
  TikTokView()
}

字符串

9cbw7uwe

9cbw7uwe1#

我有一个工作的解决方案,如果有人需要它,这里的代码:

//
//  TikTokView.swift
//
//  Created by breq on 22/12/2023.
//  https://stackoverflow.com/q/77700651/1251563
//

import SwiftUI

struct TikTokView: View {
  
  @State var isPresented: Bool = false
  @State private var name: String = ""
  
  var body: some View {
    ZStack {
      Color.red.ignoresSafeArea()
      
      VStack {
        Color.green
          .onTapGesture {
            isPresented.toggle()
          }
        TextField("Name:", text: $name)
        Color.yellow
      }
      .ignoresSafeArea(.keyboard)
      
      CommentsTestSheetView(isPresented: $isPresented)
    }
  }
}

struct CommentsTestSheetView: View {
  
  @Binding var isPresented: Bool
  @State private var text: String = ""
  
  var transition: AnyTransition = .move(edge: .bottom)
  
  var body: some View {
    ZStack(alignment: .bottom) {
      if isPresented {
        Color.black.opacity(0.5).ignoresSafeArea()
          .onTapGesture {
            isPresented.toggle()
          }
        
        ZStack(alignment: .bottom, content: {
          GeometryReader(content: {
            ScrollView(.vertical, content: {
              
              VStack {
                ForEach(0...50, id: \.self) { i in
                  Text("Comment").foregroundStyle(.pink)
                  Spacer()
                }
              }
              .frame(maxWidth: .infinity)
            })
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .padding(.bottom, 110)
            .background(.blue)
            .padding(.top, 1/3 * $0.size.height)
            
          })
          .ignoresSafeArea(.keyboard)
          
          HStack {
            Text("LOREM")
            
            TextField("TESTING", text: $text, axis: .vertical)
              .keyboardType(.asciiCapable)
              .autocorrectionDisabled(true)
              .foregroundStyle(.pink)
          }
          .frame(minHeight: 50, maxHeight: 100)
          .frame(maxWidth: .infinity)
          .background(.white)
        })
        .transition(transition)
      }
    }
    .animation(.smooth(duration: 0.2), value: isPresented)
  }
}

#Preview {
  TikTokView()
}

字符串

dphi5xsq

dphi5xsq2#

不需要手工构建,SwiftUI已经内置了Viewmodifier。所以你想要的可以这样写:

struct TikTokView: View {
    
    @State private var showComments: Bool = true
    
    var body: some View {
        Button{
            showComments.toggle()
        } label: {
            Text("show comments")
        } // a .sheet is used to show content above the current view
        .sheet(isPresented: $showComments){
            CommentView()
                .presentationDetents([.fraction(0.7)]) // with this you can
                                                       // determine how much space sheet takes
                .presentationBackground(.clear) // <-- add this to hide the background
        }
    }
}

struct CommentView: View {
    
    @State private var commentToAdd: String = ""
    
    var body: some View {
        ScrollView{
            VStack{
                ForEach(0...100, id: \.self){ index in
                    Text("comment \(index)")
                }
        }
            .frame(maxWidth: .infinity)
        }.safeAreaInset(edge: .bottom) { // the safe area inset places the view at the bottom
                                         // and will move it up when keyboard appears
            TextField("", text: $commentToAdd)
                .textFieldStyle(.roundedBorder)
                .background(.ultraThinMaterial)
        }
    }
}

字符串

相关问题