I am essentially working with this template.
#State var Scenario = 0
Picker(selection: $Scenario, label: Text("")) {
Text("1").tag(0)
Text("2").tag(1)
Text("3").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
.rotationEffect(.degrees(90))
I would like the text to be also rotated.
I've tried all ways I could think of rotating them, and exhausted Google.
Another issue is that the frame remains in the original unrotated horizontal position. Which isn't good for fitting it in.
Related
I want to setup a very simple accessoryCorner SwiftUI widget, but it displays ugly.
This is my code:
struct WidgetView: View {
#Environment(\.widgetFamily) var widgetFamily
var body: some View {
switch widgetFamily {
case .accessoryCorner:
Image(systemName: "cart")
.widgetLabel {
Text("Label")
}
default:
Text("?")
}
}
}
This yields the following watch face:
For some reason, the image (the cart) is displayed in white color on a nearly white background, i.e. it cannot be seen.
I tried various methods to set a better background, e.g. ZStack with AccessoryWidgetBackground(), background(Color.clear), etc., but none worked.
How to display the image without a background, like the day (DI) in the left upper corner?
I contacted Apple and got the following answer:
We have reviewed your request and have concluded that there is no
supported way to achieve the desired functionality given the currently
shipping system configurations.
I have a list of messages that are stored in an array and then displayed to the screen via a loop, which is within a ScrollView. What i want is when the view is loaded the scroll view is scrolled all the way to the bottom, which i attempted to do with the scrollTo function, however the scroll view stayed in the same position no matter what value i passed into it. Can someone help point me in the right direction on how to do this.
struct MessageList2: View {
#Binding var messages: [String]
var body: some View {
ScrollViewReader { value in
ScrollView() {
VStack(alignment: .leading) {
ForEach(0..<messages.count, id: \.self) { index in
Text(messages[index])
}
}
.onAppear{
value.scrollTo(messages.count)
}
}
}
}
}
Note the 'messages array receives value from another function and works just fine
I tried following examples online that showed how to use the ScrollView and scrollTo() and tried to implement it myself however the view stayed the same. Im assuming that im using the function wrong.
I also tried adding a .id(index) under Text() but that didnt seem to work.
This is an off-by-one error. Note the id's you are assigning to each items are the same the index of the elements. The max index that can appear in messages is messages.count - 1, which means the max possible id is messages.count - 1.
So instead of scrollTo(messages.count), you probably meant to scrollTo(messages.count - 1).
I cannot understand why in the simulator the layout is different from the layout displayed in xcode/preview.
struct ContentView : View {
var body: some View {
ZStack(alignment: .bottom) {
ARViewContainer()
Text("hello")
}
}
}
here the screenshots:
TLDR; I don't know why your simulator and preview don't match, but I do know why it's appearing the way that it is on the device. Are you getting any errors in the debug?
Any container views in SwiftUI will only take up the required space that they need. they will also distribute according to your settings. For example, you have a ZStack that contains a bottom alignment. You also have a ARViewContainter() that takes up a portion of that stack. They are aligned behind each other on the Z axis where the text is in front and the other container is behind. A quick way to prove this and test it is to include a background shape behind everything for example.
var body: some View {
ZStack {
Rectangle().edgesIgnoringSafeArea(.all)
.foregroundColor(Color.red)
//Your Views
}
}
This will force the ZStack to take up all available space and your other views should then align as expected. Basically, your Text is aligning to the bottom of the maximum provided space, which is being provided by your ARViewContainer()
Further Reading and Understanding
Views only take up the space required for what's in them, unless otherwise specified.
ZStacks operate on the Z axis, forward/backwards.
In your case you have a view with a set size called ARViewContainer() which takes up the width of the screen and a portion of the height. Since it's the largest view you have, the ZStack inherits that size.
Your text is smaller than the ZStack so the ZStack does NOT inherit the size. You do however have a .bottom assignment. So your text is over your ARViewContainer() and aligned to the .bottom edge of that container.
Finally the ZStack is centered in the remaining space available, giving it the impression that your .bottom isn't doing anything, when in reality it is.
Reproducing the Issue
Here is a code snippet that reproduces your issue and makes it a bit clearer and easier to understand.
var body: some View {
ZStack(alignment: .bottom) {
Rectangle().foregroundColor(Color.yellow).frame(width: 100, height: 100, alignment: .center)
Text("Test")
}
}
I am trying to loop through a list of 2-6 items. They are all Text() views for this example, and I want them to all squeeze to the left. This code below is as close as I have gotten
Why? I am simplifying the actual problem to make solving easier
HStack{
ForEach(array, id: \.self) { pageItem in
HStack{
PageDataItemView(pageItem: pageItem)
}.fixedSize()
}
VStack(){
Spacer()
}
}
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.frame(height: 40.0)
PageDataItemView for this example is just Text().
Anyway what I can't seem to solve is to make PageDataItemView's width based on the text content. In the code above they squeeze, but they all overlap each other, rather than taking their own space. Removing .fixedSize() above causes the items to fill the full width evenly.
In Android's XML I could just use "wrap_content" to produce this. While I understand this is not the ideal way to build UI here, it has to do with a complex client request.
Update:
GeometryReader { geometry in
Seems to be causing my views to break as this is inside PageDataItemView. Even when geometry isn't even used at all. Once removed everything worked as expected, curious why this effects a view indirectly. Let me know if I should remove this question.
I'm embedding a view controller with variable-height UITextView inside a parent SwiftUI VStack and the view controller sizes it's frame to the whole screen between viewDidLoad and viewDidLayoutSubviews. The UITextView expands only to the size of the text inside itself and centers itself inside the parent view.
I'm trying to add this view controller in a VStack and have it behave externally like other SwiftUI components do - sized exactly to the content it contains - but it wants to be sized to the whole screen minus the other VStack elements.
I can get the correct size of the UITextView in didLayoutSubviews and pass it upwards to SwiftUI where it can be set properly - but where do I do that?
In the example screenshot below, the orange is the embedded UIView background, the green is the UITextView and the VStack looks like this:
VStack {
HighligherVC()
Text("Tap and drag to highlight")
.foregroundColor(.gray)
.font(.caption)
}
Without being able to see more of your code, it's slightly difficult to say what the best solution would be, but based purely on this part of your question...
I can get the correct size of the UITextView in didLayoutSubviews and pass it upwards to SwiftUI where it can be set properly - but where do I do that?
I would suggest that you pass a binding property to your view controller that can be set to the calculated text view height, meaning that the view that contains your VStack would have a #State property like this:
#State private var textViewHeight: CGFloat = 0
You would then declare a #Binding property on your HighlighterVC and add an initializer like this:
#Binding var textViewHeight: CGFloat
init(textViewHeight: Binding<CGFloat>) {
self._textViewHeight = textViewHeight
}
And then you would set textViewHeight to the calculated height in your didLayoutSubviews and add a .frame modifier to your HighlighterVC like this:
VStack {
HighlighterVC(textViewHeight: self.$textViewHeight)
.frame(height: self.textViewHeight)
Text("Tap and drag to highlight")
.foregroundColor(.gray)
.font(.caption)
}
Like I said at the beginning of my answer, this solution (that I believe would work, but since I can't test it, I'm not 100% certain) is based on your thoughts about what it is that you need. Without seeing more code, it's impossible for me to say if this is the best solution.
Add fixedSize may solve this.
.fixedSize(horizontal: false, vertical: true)