NavigationView + TextField 背景

Posted

技术标签:

【中文标题】NavigationView + TextField 背景【英文标题】:NavigationView + TextField Background 【发布时间】:2020-05-06 21:45:18 【问题描述】:

我目前正在学习 SwiftUI 并构建一个待办事项列表应用程序。在 ContentView 屏幕上,我有一个 NavigationView 和一个在列表中弹出“添加新任务”文本字段的按钮。我怀疑这不是实现这一点的正确方法,但是当文本字段显示时,背景颜色不会持续存在。对于我的生活,我无法弄清楚如何设置背景颜色。如果我将文本字段移到 NavigationView 之外,我可以设置背景,但是当 NavigationView 移动以为文本字段腾出空间时,我会得到一堆黑屏闪烁。关于添加到列表时如何在文本字段上设置背景颜色或将其移出时如何修复屏幕闪烁的任何想法?感谢您的帮助。

import SwiftUI
import UIKit

struct ContentView: View 

@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(entity: ToDoItem.entity(), sortDescriptors: [NSSortDescriptor(key: "order", ascending: true)]) var listItems: FetchedResults<ToDoItem>

@State private var newToDoItem = ""
@State private var showNewTask = false
@State var isEditing = false
@State var showTaskView = false
@State var bottomState = CGSize.zero
@State var showFull = false
@State var deleteButton = false

//this removes the lines in the list view
init() 
    // To remove only extra separators below the list:
    UITableView.appearance().tableFooterView = UIView()

    // To remove all separators including the actual ones:
    UITableView.appearance().separatorStyle = .none

    UIScrollView.appearance().backgroundColor = .clear
    //UITableView.appearance().backgroundColor = .clear


var body: some View 
    ZStack
        VStack
            TitleView()

            NavigationView 
                List 
                    if showNewTask 
                        HStack
                            TextField("New task", text: self.$newToDoItem, onEditingChanged:  (changed) in
                            ) 
                                print("onCommit")
                                self.addTask(taskTitle: self.newToDoItem)
                                self.saveTasks()
                                self.showNewTask.toggle()
                                self.newToDoItem = ""
                            
                            .font(Font.system(size: 18, weight: .bold))
                            .foregroundColor(Color("Text"))

                            Button(action: 
                                self.newToDoItem = ""
                                self.showNewTask.toggle()
                            ) 
                                Image(systemName: "xmark.circle").foregroundColor(Color("button"))
                                    .font(Font.system(size: 18, weight: .bold))
                            
                        
                        .padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
                        .background(Color("addNewTask"))
                        .cornerRadius(10.0)
                    

                    ForEach(listItems, id: \.self) item in
                        HStack 
                            Button(action: 
                                item.isComplete = true
                                self.saveTasks()
                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
                                    self.deleteTaskTest(item: item)
                                
                            ) 
                                if (item.isComplete) 
                                    Image(systemName: "checkmark.circle")
                                        .font(Font.system(size: 25, weight: .bold))
                                        .foregroundColor(Color(#colorLiteral(red: 0.1616941956, green: 0.9244045403, blue: 0.1405039469, alpha: 1)))
                                        .padding(.trailing, 4)
                                 else 
                                    Image(systemName: "circle")
                                        .font(Font.system(size: 25, weight: .bold))
                                        .foregroundColor(Color("button"))
                                        .padding(.trailing, 4)
                                
                            
                            .buttonStyle(PlainButtonStyle())

                            ToDoItemView(title: item.title, createdAt: "\(item.createdAt)")
                                .onTapGesture 
                                    self.showTaskView.toggle()
                            
                            .onLongPressGesture(minimumDuration: 0.1) 
                                self.isEditing.toggle()
                                print("this is a long press test")
                            
                        
                        .listRowBackground(Color("background"))
                    
                    .onMove(perform: moveItem)
                    .onDelete(perform: deleteTask)
                
                .environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
                .navigationBarTitle(Text("ToDay"), displayMode: .large)
                .navigationBarHidden(true)
                .background(Color("background"))
            

            //ADD A NEW TASK BUTTON
            HStack 
                Spacer()
                Button(action: 
                    self.showNewTask.toggle()
                ) 
                    Image(systemName: "plus")
                        .font(.system(size: 18, weight: .bold))
                        .frame(width: 36, height: 36)
                        .background(Color("button"))
                        .foregroundColor(.white)
                        .clipShape(Circle())
                        .shadow(color: Color.black.opacity(0.2), radius: 5, x: 0, y: 5)

                
            
            .padding()
        
        .blur(radius: showTaskView ? 20 : 0)
        .animation(.default)
        .padding(.top, 30)

        //BOTTOM CARD VIEW
        TaskView()
            .offset(x: 0, y: showTaskView ? 360 : 1000)
            .offset(y: bottomState.height)
            .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.5))
            .gesture(
                DragGesture().onChanged  value in
                    self.bottomState = value.translation
                    if self.showFull 
                        self.bottomState.height += -300
                    

                    if self.bottomState.height < -300 
                        self.bottomState.height = -300
                    

                 .onEnded  value in
                    if self.bottomState.height > 50 
                        self.showTaskView = false
                    
                    if (self.bottomState.height < -100 && !self.showFull) || (self.bottomState.height < -250 && self.showFull)
                        self.bottomState.height = -300
                        self.showFull = true
                     else 
                        self.bottomState = .zero
                        self.showFull = false
                    
                
        )
    
    .background(Color("background").edgesIgnoringSafeArea(.all))

【问题讨论】:

适用于 Xcode 11.4。我只用标准替换了您的自定义颜色。 我也在 11.4。刚刚尝试使用标准颜色,似乎不起作用... 【参考方案1】:

终于搞定了。无论出于何种原因,重新处理堆栈都修复了它。

struct ContentView: View 

@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(entity: ToDoItem.entity(), sortDescriptors: [NSSortDescriptor(key: "order", ascending: true)]) var listItems: FetchedResults<ToDoItem>

@State private var showCancelButton: Bool = false
@State private var newToDoItem = ""
@State private var showNewTask = false
@State var isEditing = false
@State var showTaskView = false
@State var bottomState = CGSize.zero
@State var showFull = false
@State var deleteButton = false

var itemName = ""

init() 
    // To remove all separators including the actual ones:
    UITableView.appearance().separatorStyle = .none

    UITableView.appearance().backgroundColor = .clear


var body: some View 
    ZStack 
        VStack 
            NavigationView 
                VStack 
                    TitleView()
                        .padding(.top, 20)
                        .background(Color("background"))

                    // Enter new task view
                    if showNewTask 
                        HStack 
                            HStack 
                                TextField("New task", text: self.$newToDoItem, onEditingChanged:  (changed) in
                                ) 
                                    self.addTask(taskTitle: self.newToDoItem)
                                    self.saveTasks()
                                    self.showNewTask.toggle()
                                    self.newToDoItem = ""
                                
                                .font(Font.system(size: 18, weight: .bold))
                                .foregroundColor(Color("Text"))

                                Button(action: 
                                    self.newToDoItem = ""
                                    self.showNewTask.toggle()
                                ) 
                                    Image(systemName: "xmark.circle").foregroundColor(Color("button"))
                                        .font(Font.system(size: 18, weight: .bold))
                                
                            
                            .padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
                            .background(Color("addNewTask"))
                            .cornerRadius(10.0)

                        
                        .background(Color("background"))
                        .padding(.horizontal)
                    

                    List 
                        ForEach(listItems, id: \.self) item in
                            HStack 
                                Button(action: 
                                    item.isComplete = true
                                    self.saveTasks()
                                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
                                        self.deleteTaskTest(item: item)
                                    
                                ) 
                                    if (item.isComplete) 
                                        Image(systemName: "checkmark.circle")
                                            .font(Font.system(size: 25, weight: .bold))
                                            .foregroundColor(Color(#colorLiteral(red: 0.1616941956, green: 0.9244045403, blue: 0.1405039469, alpha: 1)))
                                            .padding(.trailing, 4)
                                     else 
                                        Image(systemName: "circle")
                                            .font(Font.system(size: 25, weight: .bold))
                                            .foregroundColor(Color("button"))
                                            .padding(.trailing, 4)
                                    
                                
                                .buttonStyle(PlainButtonStyle())

                                ToDoItemView(title: item.title, createdAt: "\(item.createdAt)")
                                .onTapGesture 
                                    //item.title = self.itemName
                                    self.showTaskView.toggle()
                                
                                .onLongPressGesture(minimumDuration: 0.1) 
                                    self.isEditing.toggle()
                                    print("this is a long press test")
                                
                            
                            .listRowBackground(Color("background"))
                        
                        .onMove(perform: moveItem)
                        .onDelete(perform: deleteTask)
                    
                    .environment(\.editMode, .constant(self.isEditing ? EditMode.active : EditMode.inactive)).animation(Animation.spring())
                    .navigationBarTitle(Text("ToDay"), displayMode: .large)
                    .navigationBarHidden(true)
                    .background(Color("background"))
                
                .background(Color("background").edgesIgnoringSafeArea(.all))
            

            HStack 
                Spacer()
                Button(action: 
                    //withAnimation()
                    self.showNewTask.toggle()
                    //
                ) 
                    Image(systemName: "plus")
                        .font(.system(size: 18, weight: .bold))
                        .frame(width: 36, height: 36)
                        .background(Color("button"))
                        .foregroundColor(.white)
                        .clipShape(Circle())
                        .shadow(color: Color.black.opacity(0.2), radius: 5, x: 0, y: 5)

                
            
            .padding()
        
        .blur(radius: showTaskView ? 20 : 0)

        //BOTTOM CARD VIEW
        TaskView()
            .offset(x: 0, y: showTaskView ? 360 : 1000)
            .offset(y: bottomState.height)
            .animation(.timingCurve(0.2, 0.8, 0.2, 1, duration: 0.5))
            .gesture(
                DragGesture().onChanged  value in
                    self.bottomState = value.translation
                    if self.showFull 
                        self.bottomState.height += -300
                    

                    if self.bottomState.height < -300 
                        self.bottomState.height = -300
                    

                 .onEnded  value in
                    if self.bottomState.height > 50 
                        self.showTaskView = false
                    
                    if (self.bottomState.height < -100 && !self.showFull) || (self.bottomState.height < -250 && self.showFull)
                        self.bottomState.height = -300
                        self.showFull = true
                     else 
                        self.bottomState = .zero
                        self.showFull = false
                    
                
        )
    
    .animation(.default)
    .background(Color("background").edgesIgnoringSafeArea(.all))


func moveItem(indexSet: IndexSet, destination: Int)
    let source = indexSet.first!
    if source < destination 
        var startIndex = source + 1
        let endIndex = destination - 1
        var startOrder = listItems[source].order
        while startIndex <= endIndex 
            listItems[startIndex].order = startOrder
            startOrder = startOrder + 1
            startIndex = startIndex + 1
        
        listItems[source].order = startOrder
     else if destination < source 
        var startIndex = destination
        let endIndex = source - 1
        var startOrder = listItems[destination].order + 1
        let newOrder = listItems[destination].order
        while startIndex <= endIndex 
            listItems[startIndex].order = startOrder
            startOrder = startOrder + 1
            startIndex = startIndex + 1
        
        listItems[source].order = newOrder
    
    saveTasks()
    self.isEditing.toggle()


func deleteTask(indexSet: IndexSet)
    let source = indexSet.first!
    let listItem = listItems[source]
    //self.deleteButton.toggle()
    managedObjectContext.delete(listItem)
    saveTasks()


func deleteTaskTest(item: ToDoItem)
    managedObjectContext.delete(item)
    saveTasks()


func addTask(taskTitle: String) 
    let newTask = ToDoItem(context: managedObjectContext)
    newTask.title = taskTitle
    newTask.order = (listItems.last?.order ?? 0) + 1
    newTask.createdAt = Date()


func saveTasks() 
    do 
        try managedObjectContext.save()
     catch 
        print(error)
    

【讨论】:

以上是关于NavigationView + TextField 背景的主要内容,如果未能解决你的问题,请参考以下文章

NavigationView 顶部的额外空间

如何在 NavigationView 中设置列​​表的背景颜色

NavigationView + TextField 背景

无法修改 NavigationView 中的 TextView

PageTabViewStyle 打破 NavigationView

Android NavigationView 导航抽屉的使用