SwiftUI - ScrollViewReader scroll to top including padding (anchor plus constant) - swiftui

I have a ScrollViewReader and the scrollTo method works.
proxy.scrollTo(target, anchor: .top)
The item which is scrolled to is completely aligned with the .top-Anchor.
Now I want to include the padding of 7px.
Is there a SwiftUI equivalent to the NSLayoutAnchor below or any other method to make the green overlay always align with the List-Element.
NSLayoutAnchor(equalTo:self.view.topAnchor constant:7)

Related

SwiftUI Remove Extra Space between NavigationTitle and TextView

Started learning SwiftUI, I want to remove this highlighted space between navigation title and Text inside VStack.
If you were to remove the NavigationView and had your VStack as the top-level view in your body, you'd see much the same layout.
That's because its frame is smaller than the frame available for it (in this case, most of the screen) and by default the smaller internal view gets centered both horizontally and vertically.
To move the text to the top of the screen, you need to ensure that your view will grow in size. The easiest way will be add to add a Spacer to the bottom of the VStack:
VStack(alignment: ...) {
Text("...")
Text("...")
Spacer()
}
Another approach would be to wrap your VStack in a scroll view. This view will automatically expand itself to fill the height, and layout its subviews (your VStack) from the top downwards:
ScrollView {
VStack(alignment: ...) {
Text("...")
Text("...")
}
}
Each approach has upsides and downsides depending on how much other data you expect to also be in the view.
You could also manually adjust the frame of your VStack using the .frame() modifier:
VStack(alignment: ...) {
Text("...")
Text("...")
}
.frame(maxHeight: .infinity, alignment: .top)
This would give you much the same effect as using the spacer. But the spacer version is a better way to go, especially if you're only starting out with SwiftUI layout.

How to overlay view on top of multiple other views in a VStack in SwiftUI

In SwiftUI I currently have a VStack of views, and I'd like to put an overlay over the bottom two views, like this:
VStack {
Spacer()
Group {
centerView
Spacer()
}
.overlay(overlayedView)
}
The goal of the above layout is ensure that centerView is vertically centered, while also ensuring that the overlayedView goes from the top of centerView all the way to the bottom of the VStack.
However, the above code actually results in one instance of overlayedView getting overlayed on top of centerView and another overlayedView getting overlayed on top of the bottom Spacer. But what I want is a single overlayedView spread on top of both centerView and the bottom Spacer.
How can I achieve my desired behavior?
Using Group will add view modifiers to all the subviews of the group, resulting in 2 seperate overlays. To have one common overlay, you can use VStack instead of Group.
VStack {
Spacer()
VStack {
centerView
Spacer()
}
.overlay(overlayedView)
}

SwiftUI: Offset Popover Anchor by Constant Amount

NOTE: This is a macOS question, not iOS.
I would like to anchor a SwiftUI Popover exactly 70 points to the right of the bottom-leading corner of the "20 Hours Ago" button in this image:
I do NOT want to anchor the popover a certain percentage of the button's width (which would be using UnitPoint). The button's text is updated as the user selects different items in the popover and as the button's width changes, the percentage-based anchor point moves, causing the popover to jump around horizontally. No good. I also don't want to anchor the popover exactly at the bottom-leading corner, as that looks dumb.
The trouble is, I can't figure out what to feed SwiftUI to get a constant, simple horizontal offset for the anchor point of the popover. I'm here:
.popover(isPresented: $isShowingPopover, attachmentAnchor: .point(.bottomLeading), arrowEdge: .bottom, content: {
...
})
How do I specify: "start at the bottom-leading point and then go 70 points to the right"? (Based on the strings that will appear in the button, I KNOW 70 is a good-looking anchor point for all cases.)
You can use .rect:
That defines absolute offsets to the parent content rect, but then you'll have to specify y offset as well.
.popover(isPresented: $show1,
attachmentAnchor: .rect(.rect(CGRect(x: 70, y: 15, width: 0, height: 0))),
arrowEdge: .bottom)
{
Text("Popover")
.frame(width: 200, height: 100)
}

Prevent Navigation Bar from collapsing and being sticky when on scroll SwiftUI / UIKit

I would like the NavigationBar (from a SwiftUI NavigationView) to just stay large and scroll out whenever I scroll in a Pages ScrollView. Right now it is always collapsing and showing even on scroll in ".inline"-display mode. So when I try to completely hide it I also hide the large title I'd like to keep.
Is there a way to just let it stay large and just scroll out?
Any solution in SwiftUI or UIKit is appreciated as I can introspect from UIKit.
I especially don't want the NavigationBar to be hidden and rebuild by VStack or HStack as this causes loosing all Navigation Gestures like swiping back to the previous Navigation View and so...
Here is a basic codesnipped to recreate
struct TestTestView: View {
var body: some View {
NavigationView {
ScrollView() {
Color.green
.frame(height: 1000)
}
.navigationTitle("Test")
}
}
}

Make view fall in multiple rows like text in SwiftUI

I have a similar problem to this: SwiftUI HStack with wrap and dynamic height
But I want this tags to aligned in center instead of left aligned. I tried but can't make it work.
You can try VStack with alignment.
VStack(alignment: .center) {
// your views
}
SkillChipView is just rename of TagCloudView.