I need to create a view that has 2 Pickers and 2 DatePickers.
In order to avoid having them overlapping each other, I used .clipped(). However, this is not working.
I can successfully resize the pickers, but I cannot limit the "selection area" to their frame size.
Here is my code:
VStack(spacing: 10) {
Picker(selection: self.$dayTypeSelectedIndex, label: Text("")) {
ForEach(0 ..< self.dayTypes.count, id: \.self) {
Text(self.dayTypes[$0])
.foregroundColor(Color.black)
}
}
.pickerStyle(SegmentedPickerStyle())
.labelsHidden()
.clipped()
Spacer()
Group {
DatePicker("", selection: self.$dateIntervalStart, displayedComponents: .hourAndMinute)
.labelsHidden()
.colorInvert()
.colorMultiply(Color.black)
.frame(maxHeight: 50)
.clipped()
Spacer()
Text("às")
.foregroundColor(Color.black)
Spacer()
DatePicker("", selection: self.$dateIntervalEnd, displayedComponents: .hourAndMinute)
.labelsHidden()
.colorInvert()
.colorMultiply(Color.black)
.frame(maxHeight: 50)
.clipped()
}
Spacer()
HStack {
Picker(selection: self.$tripNotificationDelta, label: Text("")) {
ForEach(0...60, id: \.self) {
Text($0 < 10 ? "0\($0)" : "\($0)")
.foregroundColor(Color.black)
}
}
.labelsHidden()
.frame(maxWidth: 50, maxHeight: 50)
.clipped()
Text("mins before trip")
.foregroundColor(Color.black)
}
}
}
What am I doing wrong?
I'm using XCode 12. Plus, this interface is being built for devices not running iOS 14.
Thanks!
So, I figured it out. Just put .compositingGroup() before .clipped(). Something like this:
DatePicker("", selection: self.$dateIntervalEnd, displayedComponents: .hourAndMinute)
.labelsHidden()
.colorInvert()
.colorMultiply(Color.black)
.frame(maxHeight: 50)
.compositingGroup()
.clipped()
As mentioned in here
Adding this simple extension solves the problem with overlapping scroll areas. You don't need to add .compositingGroup() and .clipped()
extension UIPickerView {
override open var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric, height: super.intrinsicContentSize.height)
}
}
Related
I have a date picker inside a bottom sheet view.
When the bottom sheet opens, the first time I choose a day, the date picker height changes.
P.S: If I set a custom height for the picker using .frame, the date picker just becomes smooshed inside the frame.
var body: some View {
VStack {
HStack {
Text("date_picker_title".ld())
.font(.custom(Font.rRegular, size: 12))
.padding()
Spacer()
}
HStack {
Text(date.prettyDate)
.font(.custom(Font.rMedium, size: 28))
Spacer()
Text(date.prettyHour)
.font(.custom(Font.rMedium, size: 28))
}.padding(.horizontal)
Seperator(cellHeight: 0).frame(height: 2)
Spacer().frame(height: 6)
DatePicker("", selection: $date, in: Date()..., displayedComponents: .date)
.datePickerStyle(.graphical)
.labelsHidden()
.tint(Color.appPurple)
.padding(.horizontal)
.padding(.bottom, -10)
Seperator(cellHeight: 0).frame(height: 2)
HStack {
Text("date_picker_enter_time".ld())
.font(.custom(Font.rRegular, size: 12))
DatePicker("", selection: $date, displayedComponents: .hourAndMinute)
.labelsHidden()
.tint(Color.appPurple)
Spacer()
}.padding()
HStack {
Button {
completion(nil)
} label: {
Text("date_picker_cancel".ld())
.font(.custom(Font.rRegular, size: 14))
.foregroundColor(Color.appPurple)
}
Spacer()
Button {
completion(date)
} label: {
Text("date_picker_ok".ld())
.font(.custom(Font.rRegular, size: 14))
.foregroundColor(Color.appPurple)
}
}.padding(.horizontal)
Spacer().frame(height: 50)
}
.frame(maxWidth: .infinity)
.background(Color.appLightPurple)
.padding(.bottom, -50)
}
Lately started learning SwiftUI and I ran into a problem.
I tried putting image and text component and it didn't break the line.
Someone have an idea to solve it?
This is my code:
struct RestaurantOverlay: View {
var amountOfStars: Int
var body: some View {
ZStack {
Text("Burger")
.font(.system(size: 17.5))
.foregroundColor(.white)
.fontWeight(.heavy)
Image(systemName: "star.fill")
.font(.system(size: 13))
.foregroundColor(.white)
.fontWeight(.medium)
}
.padding(10)
.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
}
}
ZStack {
HStack {
Text("Burger")
.font(.system(size: 17.5))
.foregroundColor(.white)
.fontWeight(.heavy)
Image(systemName: "star.fill")
.font(.system(size: 13))
.foregroundColor(.white)
.fontWeight(.medium)
}
.padding(10)
.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
}
You can change HStack to VStack if you want vertically.
All
I'm new to iOS and SwiftUI (2 months). I'm struggling to understand the following behavior and hope someone can point me as to how I can diagnose.
I have this code successfully generating this view in the preview provider
however when I run it on a device or in the simulator the fonts change (happens for system images also) to look more like this (scaled up).
The view below is rendered inside of a very generic tabview - I cant fathom it at all and could use some guidance.
Thanks
Craig
var body: some View {
VStack(spacing: 0.0) {
HStack(alignment: .top){
Text(player.firstName)
.bold()
Text(player.lastName)
.bold()
}
.font(.title)
HStack {
Image(uiImage: UIImage(data: player.playerPhoto) ?? UIImage())
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: /*#START_MENU_TOKEN#*/100/*#END_MENU_TOKEN#*/, height: 100)
.clipShape(Circle())
.overlay(Circle().stroke(Color.purple, lineWidth: 4.0))
Spacer()
VStack {
Text("lifetime averages")
.font(.body)
.foregroundColor(Color.gray)
HStack {
Spacer()
VStack {
Text("Batting")
.font(.title2)
.bold()
Text("\(battingAverage, specifier: "%.3f")")
}
.padding(.leading)
if isPitcher {
Spacer()
VStack {
Text("ERA")
.font(.title2)
.bold()
Text("\(earnedRunAverage, specifier: "%.2f")")
}
.padding(.trailing)
Spacer()
}
}
}
Spacer()
}
HStack {
VStack {
Text("\(noTeams)")
.font(.headline)
Text("teams")
.font(.subheadline)
.foregroundColor(Color.gray)
}
.padding(.leading, 10)
Spacer()
VStack {
Text("\(noSeasons)")
.font(.headline)
Text("seasons")
.font(.subheadline)
.foregroundColor(Color.gray)
}
Spacer()
VStack {
Text("\(noGames)")
.font(.headline)
Text("games")
.font(.subheadline)
.foregroundColor(Color.gray)
}.padding(.trailing, 10)
}
HStack{
Spacer()
Text("All Lifetime Stats >")
.font(.callout)
.foregroundColor(Color.blue)
}
}
.frame(width: 350, height: 200, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
}
Your code does not specify a .font(...) for those two Text elements.
Is it possible you have set the default font somewhere else?
I can reproduce what you're getting by doing this (using PlayerView as a stand-alone view, not in a table).
If using UIKit App Delegate, in willConnectTo session:
let contentView = PlayerView()
.font(.largeTitle)
or, if using SwiftUI App:
#main
struct TestApp: App {
var body: some Scene {
WindowGroup {
PlayerView()
.font(.largeTitle)
}
}
}
I am working on SwiftUI to make a widget and I can't figure out if I'm doing something wrong or there's a bug in SwiftUI.
I have an Image that I use as a background and at the top there's a text. If I apply resizable() to the Image it also affects the behaviour of the text.
var body: some View {
ZStack {
VStack {
Image(affirmation.customImageName ?? "c_0")
.resizable()
.scaledToFill()
.clipped()
}
HStack {
Text(affirmation.title)
.font(.body)
.multilineTextAlignment(.leading)
.lineLimit(nil)
Spacer()
}
.padding(.leading, 5)
.padding(.top, 5)
}
}
Creates this view:
While this code:
var body: some View {
ZStack {
VStack {
Image(affirmation.customImageName ?? "c_0")
.scaledToFill()
.clipped()
}
HStack {
Text(affirmation.title)
.font(.body)
.multilineTextAlignment(.leading)
.lineLimit(nil)
Spacer()
}
.padding(.leading, 5)
.padding(.top, 5)
}
}
Creates this view:
My question is how I can add a NavigationLink to the code below without changing the UI. I tried around for a few hours, but unfortunately without success. So if someone could help me that would be nice. I also found this but unfortunately, the answers did not work for me. Maybe I did something wrong
import SwiftUI
struct ContentView: View {
var body: some View {
UITableView.appearance().separatorStyle = .none
return NavigationView {
List {
CardView()
.listRowInsets(EdgeInsets())
}
.navigationBarTitle("Title")
}
}
}
struct CardView: View {
var body: some View {
VStack {
// NavigationLink(destination: EmptyView()) {
Image("Image")
.resizable()
.aspectRatio(contentMode: .fit)
HStack {
VStack(alignment: .leading) {
Text("Title")
.font(.system(size: 20))
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(3)
Text("Subtitle")
.font(.caption)
.foregroundColor(.secondary)
}
.layoutPriority(100)
Spacer()
Image(systemName: SFSymbolName.chevron_right)
.foregroundColor(.secondary)
.font(Font.body.weight(.semibold))
}
.padding([.leading, .bottom, .trailing], 16)
.padding(.top, 5)
// }
}
.background(Color("CustomCardViewColor"))
.cornerRadius(10)
.padding(.all, 0.1)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.1), lineWidth: 1)
)
.padding([.top, .leading, .trailing])
}
}
The reason your UI changes drastically is that NavigationLink wraps its content in an implicit HStack, placing your Image to the left of your HStack. You have a couple options, depending on whether you want to use the automatic disclosure chevron or your own styled one.
To use the system chevron:
HStack {
VStack(alignment: .leading) {
Text("Title")
.font(.system(size: 20))
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(3)
Text("Subtitle")
.font(.caption)
.foregroundColor(.secondary)
}
.layoutPriority(100)
Spacer()
// this simply places the chevron approximately where yours is
NavigationLink(destination: EmptyView()) {
EmptyView()
}
}
If you want your own:
HStack {
VStack(alignment: .leading) {
Text("Title")
.font(.system(size: 20))
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(3)
Text("Subtitle")
.font(.caption)
.foregroundColor(.secondary)
}
.layoutPriority(100)
Spacer()
// this hidden NavigationLink makes the whole row clickable
NavigationLink(destination: EmptyView()) {
EmptyView()
}.opacity(0)
// your chevron is displayed
Image(systemName: SFSymbolName.chevron_right)
.foregroundColor(.secondary)
.font(Font.body.weight(.semibold))
}
The top is with the system chevron, the bottom uses yours
You may just wrap it around the image of chevron_right. So you can click it to the next page
HStack {
VStack(alignment: .leading) {
Text("Title")
.font(.system(size: 20))
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(3)
Text("Subtitle")
.font(.caption)
.foregroundColor(.secondary)
}
.layoutPriority(100)
Spacer()
NavigationLink.init(destination: Text("Temp Link")) {
Image(systemName: SFSymbolName.chevron_right)
.foregroundColor(.secondary)
.font(Font.body.weight(.semibold))
}
}