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
Related
Here is my code:
import SwiftUI
struct ContentView: View {
var link: some View {
NavigationLink(destination: OtherView()) {
Text("NLTitle")
}
.foregroundColor(.blue)
}
var body: some View {
NavigationView {
List {
ZStack {
HStack {
Text("1")
Spacer()
}.padding([.leading, .trailing], 20)
HStack {
Spacer()
Text("2")
.multilineTextAlignment(.center)
.frame(
alignment: .center
)
Spacer()
}
.padding([.leading, .trailing], 20)
HStack {
Spacer()
link
}.padding([.leading, .trailing], 20)
}
}
}
}
}
I have a NavigationLink (named 'link') in a list cell. I would like for the Text within 'link' to be to the rightmost side of the view. To try to accomplish this, I inserted 'link' in an HStack and put a Spacer() before it to try and push it to the rightmost part of the view. When I run the app though, the Text ends up in between Text("1") and Text("2") and I can't figure out why. I want Text("1") to be in the leftmost part of the view, Text("2") to be in the center of the view, and 'link' to be in the rightmost part of the view. I have provided visuals (the colors aren't important, I just wanted to make the different Texts clear):
Desired layout:
What I get instead:
I found that if I take everything out of the List view I get my desired layout. Also, if I keep everything in the List view and replace the NavigationLink with a Button I get my desired layout. The goal is to get the desired layout without having to change either of these aspects.
For the sake of clarity, I didn't include the code for OtherView() as I don't think it's necessary for this question.
The "quick" fix is to add fixedSize() to the NavigationLink
var link: some View {
NavigationLink(destination: Text("OtherView()")) {
Text("NLTitle")
}
.foregroundColor(.blue)
.fixedSize()
}
That will allow the link to shrink.
NavigationView{
List{
VStack{
Text("EdwardCullen")
.padding(.vertical, -20)
AsyncImage(url)) { image in
image
.center()
} placeholder: {
ProgressView()
}
}
Text("Test")
}
.navigationTitle("EdwardCullen's Profile")
.navigationBarTitleDisplayMode(.inline)
}
Picture of what I want
I included a picture of what I want kind of, so basically "Status" on the left side of the Text and "Online" on the total other side. I also would preferably want "Online" to be green, so I think I need to use two different Text views, but how exactly would I do this in a list? Is there any good way to do this?
The way I did what is in the picture is just adding many spaces to Text like this, but obviously that is not very smart and also not exactly what I want.
Text("First Second")
Use HStack{} plus Spacer(). (Code is below the image)
var body: some View {
VStack {
HStack {
Text("First")
Spacer() //this one
Text("Second")
}
.padding()
.background(.blue)
.cornerRadius(15)
}
}
Use a spacer "Spacer()". This is an adaptive view that expands as much as it can.
NavigationView{
List{
VStack{
Text("EdwardCullen")
.padding(.vertical, -20)
AsyncImage(url)) { image in
image
.center()
} placeholder: {
ProgressView()
}
}
# new code here
HStack {
Text("Status")
Spacer()
Text("Online")
.foregroundColor(.green)
}
}
.navigationTitle("EdwardCullen's Profile")
.navigationBarTitleDisplayMode(.inline)
}
Just Use a HStack and put a spacer between two text .
sample code :
HStack{
Text("Status")
Spacer()
Text("Online")
}.cornerRadius(8)
you may use this anywhere you want .
Sample Output:
I’m having issues when using NavigationView and NavigationLinks on iPadOS 15. Currently running Dev Beta of iPadOS 15.3 (19D5026g), but I’ve had this issue since the release of 15.1. When I’m using my app as usual, nothing is wrong. But when I turn the app into a Slide Over, the detail works, but when I click “Back” and pop the detail back, I’m unable to click the NavLink (it doesn’t push the detail). When I turn the app back to full screen, everything is pretty much fine. Has anyone noticed something like that?
Edit: Just found out that Split Screen does the exact same thing.
Here’s my code:
struct ContentView: View {
var body: some View {
NavigationView {
SideBar()
.navigationBarTitle("SideBar")
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {}
//Button which opens options
}
DetailView()
.navigationBarTitle(“Detail”, displayMode: .large)
}
}
}
//SideBar:
struct SideBar: View {
var body: some View {
VStack{
Spacer()
VStack {
NavigationLink(destination: DetailView()) {
Text(“DetailView”)
.font(.headline)
}
NavigationLink(destination: OtherDetailView()) {
Text("Other Detail View")
.font(.headline)
}
}
Spacer()
}
}
}
//DetailView and OtherDetailView
struct DetailView: View {
var body: some View {
VStack {
Spacer()
Text("Hello World!")
Spacer()
}
.navigationBarTitle(“Detail”)
}
}```
Thanks for your help!
Found the solution myself some time ago, so I figured I'd post it here in case someone experiences the same behavior.
The right way to do what I was trying to do is apparently by using a list with this modifier:
.listStyle(SidebarListStyle())
That seemed weird to me, but I haven't found a different way to accomplish the thing I wanted to.
If I use DatePicker inside a Form, it will render just like I want. At first it is just one line with the label and the current value. When the user clicks, it will expand and show the date picker wheel.
Example:
Form {
DatePicker(selection: $dueDate, displayedComponents: .date) {
Text("Due date")
}
}
Expands to this on user click:
Now the question is; is it possible to get this behaviour outside a Form? - The Form makes things look ugly in my context. I do not want the gray background or the drop shadow.
Do anybody have a solution for this, or is a custom implementation needed?
My first attempt with Form just around the DatePicker, gave me this: :-)
Ok, now I have found something that seems to work.
var body: some View {
VStack(spacing: 0) {
VStack(alignment: .leading){
Text("Due date")
Text(formattedDate)
Divider().background(Color.gray)
}.frame(minWidth: 0, maxWidth: .infinity).onTapGesture {
withAnimation {
self.showSelect.toggle()
}
}
if showSelect {
DatePicker("", selection: $date, displayedComponents: [.date]).labelsHidden()
}
Spacer()
}
}
I have not included all the logic, but this is a good place to start.
The textField on my SwiftUI app is getting cut off. But it doesn't happen every time. It seems to happen at random.
Here is the code I'm using:
var body: some View {
VStack {
Spacer()
// Target row
HStack {
Text("Put the bullseye as close as you can to:")
Text("\(target)")
}
Spacer()
// Slider row
HStack {
Text("1")
Slider(value: $sliderValue, in: 1...100) {_ in
print(self.sliderValue)
}
Text("100")
}
Spacer()
// Hit me button row
Button(action: {
print("Button pressed")
self.alertIsVisible = true
}) {
Text(/*#START_MENU_TOKEN#*/"Hit Me!"/*#END_MENU_TOKEN#*/)
}
.alert(isPresented: $alertIsVisible) { () -> Alert in
let roundedValue = Int(sliderValue.rounded())
let score = pointsForCurrentRound()
return Alert(title: Text("Hello there!"), message: Text("The slider's value is \(roundedValue)!\n" +
"You scored \(score) points this round"
), dismissButton: .default(Text("Awesome")))
}
Spacer()
// Score and start over button row
HStack {
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Start Over")
}
Spacer()
Text("Score:")
Text("999999")
Spacer()
Text("Round:")
Text("999")
Spacer()
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/) {
Text("Info")
}
}
.padding(.bottom, 20)
}
}
I've tried adding padding trailing the text field and before the target. I've tried adding padding to the leading edge of the target. I've tried giving using the frame method on the text field to add a min length. None of these work. Any ideas?
Thanks
You may add fixedSize() to lock the labels.
HStack {
Text("Put the bullseye as close as you can to:").fixedSize()
Text("\(target)").fixedSize()
}
I just came across this exact situation! After a few moments of searching, trial, and errors, I finally figured it out. The text view is trying to resize and one of the parent views have animations enabled. If anyone having this same issue adds .animation(nil) to the Text, this will likely solve the issue.
VStack {
Text("\(Int(self.viewModel.ProgressPercentage * 100.0))%")
.font(.largeTitle)
.animation(nil)
}
Good luck!