With Beta 5 of Xcode 11 I get the warning:
"'buttonStyle' is deprecated: Use concrete 'PrimitiveButtonStyle' types directly instead."
I tried a couple of things, but didn't find out how to fix this.
Button(action: { }) {
Text("Hello")
}.buttonStyle(.plain)
Replace .plain with PlainButtonStyle():
Button(action: { }) {
Text("Hello")
}.buttonStyle(PlainButtonStyle())
Related
I have a tabView and I'm trying to change it's color. Using accentColor(:_) works but it's going to be deprecated.
TabView {
AppetizerListView()
.tabItem {
Image(systemName: "house")
Text("Home")
}
AccountView()
.tabItem {
Image(systemName: "person")
Text("Account")
}
OrderView()
.tabItem {
Image(systemName: "bag")
Text("Order")
}
}
.accentColor(Color("brandPrimary"))
Instead I've tried to use .tint(:_) as Apple suggests but is not working (it builds but does not change the color).
TabView {
AppetizerListView()
.tabItem {
Image(systemName: "house")
Text("Home")
}
AccountView()
.tabItem {
Image(systemName: "person")
Text("Account")
}
OrderView()
.tabItem {
Image(systemName: "bag")
Text("Order")
}
}
.tint(Color("brandPrimary"))
I also tried using .tint(_:) in each TabItem but it's also not working.
Any idea of what's going on or which is the correct way of making my code work as expected without using deprecated functions?
Maybe I'm using tint in a wrong way
Thanks!
I've found the solution to the problem, but I'll leave the post here for anyone who has the same problem.
What you have to do is to go to the Assets folder and define the AccentColor (that it has to be already created) as the color that you want your bar to be.
No modifiers have to be added to the tabView and it will automatically be showing the tabView with the color you defined as the AccentColor in your Assets folder.
I'm trying to use Picker on .contextMenu of navigationBarItems. However, the behavior is not as I would expect and I can't tell if this is Apple bug or if I'm doing something wrong (XCode 13.4).
After the user selects an item from the dropdown, the variable value do change but reopening the context menu, the wrong item is marked as "selected".
I've created the most basic demo to illustrate it. Same behavior on real device (iPhone 11 / iOS 15.4.1).
struct ContentView: View {
#State private var isAutoRefresh = true
var body: some View {
NavigationView {
Text("Auto refresh is: \(String(isAutoRefresh))")
.navigationBarTitle("Demo")
.navigationBarItems(
trailing:
Button(action: {}, label: {
Image(systemName: "arrow.clockwise")
})
.contextMenu {
Picker(selection: self.$isAutoRefresh, label: Text("")) {
Text("Manual refresh").tag(false)
Text("Auto refresh").tag(true)
}
.pickerStyle(InlinePickerStyle())
}
)
}
}
}
Is this a bug? Is there any workaround I can use?
Context menu is created once and cached, so we need to rebuild it once anything changed outside.
Here is a fix. Tested with Xcode 13.3 / iOS 15.4
.contextMenu {
Picker(selection: self.$isAutoRefresh, label: Text("")) {
Text("Manual refresh").tag(false)
Text("Auto refresh").tag(true)
}
.pickerStyle(InlinePickerStyle())
}.id(isAutoRefresh) // << here !!
Alternate: Just to use Menu instead of Button with context menu (if applicable by design), like
Menu {
Picker(selection: self.$isAutoRefresh, label: Text("")) {
Text("Manual refresh").tag(false)
Text("Auto refresh").tag(true)
}
.pickerStyle(InlinePickerStyle())
} label: {
Image(systemName: "arrow.clockwise")
}
With .onDelete() attached to the ForEach, nothing happens - cannot swipe to delete nor does tapping Edit show anything. Not sure what I've done wrong. It compiles fine in simulator and on my iPhone (iOS 14.5) Here's my actual code.
NavigationView {
List {
ForEach(medicines) { medicine in
HStack {
VStack(alignment: .leading) {
Text("\(medicine.name!) \(medicine.strength) \(medicine.unit!)" as String)
.font(.headline)
Text("\(medicine.quantity) x \(medicine.form!) \(medicine.direction!)" as String)
.font(.subheadline)
}
}
.frame(height: 50)
}
.onDelete(perform: deleteMedicines)
.listStyle(PlainListStyle())
.navigationBarTitle("Medicines")
.navigationBarItems(leading: EditButton(), trailing: Button(action: {
self.showingAddScreen.toggle()
}) {
Image(systemName: "plus")
})
.sheet(isPresented: $showingAddScreen) {
AddMedicineView().environment(\.managedObjectContext, self.viewContext)
}
}
}
Then here's the deleteMedicines() function:
private func deleteMedicines(offsets: IndexSet) {
withAnimation {
offsets.map { medicines[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
I've seen a few different ways of doing this and I've tried a few. I had it working when I was first playing around with List. The deleteMedicines code is borrowed from Xcode template for Core Data.
Provided code is not testable, but try to keep only onDelete modifier on ForEach, everything else move below onto List (placement of modifiers are important and can be a reason of your issue), like
NavigationView {
List {
ForEach(medicines) { medicine in
// content here
}
.onDelete(perform: deleteMedicines) // << here !!
}
.listStyle(PlainListStyle())
.navigationBarTitle("Medicines")
.navigationBarItems(leading: EditButton(), trailing: Button(action: {
self.showingAddScreen.toggle()
}) {
Image(systemName: "plus")
})
.sheet(isPresented: $showingAddScreen) {
AddMedicineView().environment(\.managedObjectContext, self.viewContext)
}
I'm currently working on Project 4 of #hackingwithswift. I'm having the problem of not being able to change the style of my picker from within a form view.
Here's a little snippet of the code I'm working on. Please assume the rest of the code is correct. No matter what modifier I put in .pickerStyle(), I always get the error:
Type 'WheelPickerStyle.Type' cannot conform to 'PickerStyle'; only
struct/enum/class types can conform to protocols
NavigationView{
Form{
Section(header: Text("When do you want to wake up?") .font(.headline)) {
DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
.datePickerStyle(WheelDatePickerStyle())
.labelsHidden()
}
Section(header: Text("Desired amount of sleep")
.font(.headline)) {
Stepper(value: $sleepAmount, in: 4...12, step: 0.25) {
Text("\(sleepAmount, specifier: "%g") hours")
}
}
Section(header: Text("Daily coffee intake")
.font(.headline)) {
Picker("Number of coffees had in a day", selection: $coffeeAmount) {
Text("1")
Text("2")
Text("3")
}
.pickerStyle(WheelPickerStyle)
}
Can anyone help me out? Please explain what I'm doing wrong, I'm a beginner!
Thanks in advance!
In your code
Picker("Number of coffees had in a day", selection: $coffeeAmount) {
Text("1")
Text("2")
Text("3")
}
.pickerStyle(WheelPickerStyle)
}
You should use WheelPickerStyle() instead of WheelPickerStyle
I have this script:
List {
//code
}.presenation($displayAlert) {
Alert(title: Text("Start1"), message: Text("other...."), dismissButton: .default(Text("Go!")))
}
I receive error:
"Protocol type 'Any' cannot conform to 'View' because only concrete types can conform to protocols"
I think that the .presentation is deprecate on Version 11.0 (11A420a)
How can I fix this error?
Thank you!
To show an alert you need to use the .alert modifier as the .presentation modifier was deprecated in Beta 4.
Here is a quick example showing how to use it.
struct ContentView: View {
#State var showAlert = false
var body: some View {
List {
Button(action: {
self.showAlert.toggle()
}) {
Text("press me")
}
}.alert(isPresented: $showAlert) {
Alert(title: Text("Title"), message: Text("Message"), dismissButton: .default(Text("OK!")))
}
}
}
You may also want to consider updating your version of Xcode as 11.2 was released today