SwiftUI: How can i present a Popup using Navigation Link - swift

I have this code embed in a Navigation View and i want RankingUserDetail presented as a Pop-up, i've tried changing the size of the View, using View.popOver style and looking for the presenting methods, can't figure out.
Already tried to change the frame of view also, but it keeps resizing to fit device screen.
Thanks for the attention
List(UsersList.users){ value in
NavigationLink(destination:
RankingUserDetail(user: value)){
RankingViewRow(user: value,rowNumber: self.UsersList.users.firstIndex(where: {$0.id == value.id})!,needAppearance: 0).frame(width: 343, height: 116)
}
}

Related

How to show animation when open new Window in SwiftUI

I have Bottom sheet I want to show it above TabBar so user tab on button inside List and it show options as Bottom sheet view
1st. I used SwiftUIX with OverlayWindow
like this
.windowOverlay(isKeyAndVisible: self.$optionsShown, {
GeometryReader { _ in
BottomSheetView(
isOpen: $optionsShown
) {
if optionsShown {
OptionsView()
}
}
.edgesIgnoringSafeArea(.all)
}
})
it working but without animation !
2nd. Then I read this Post
I tried it, it working fine with animation if I create Window inside SceneDelegate
but If I create Window outside SceneDelegate it will work without animation like SwiftUIX
Inside SceneDelegate :
Demo Project
Outside SceneDelegate :
Demo Project
I need to create new window inside my view because I will need to pass some values, and I used bottom sheet on multiple view with different views
but I cannot figure out why the animation won't work outside SceneDelegate

ScrollView nested in TabView reset position to start while changing tab

I'm experimenting with SwiftUI and I found a weird behaviour of ScrollView when nested in a TabView. If I swipe the ScrollView down and then do a slow gesture to swipe to the next tab, it sometimes reset the scrollView Position to the start. I'm not sure how to explain it well so here is a gif:
I'm trying to understand what cause this and if there is a way to avoid it.
Here is the code I use:
var body: some View {
TabView(selection: $selectedTab,
content: {
ForEach(coreData.pageList, id: \.self) { page in
if(coreData.pageList[page] == nil) {
ProgressView().onAppear(perform: {
loadPage(page: page)
})
} else {
ScrollView {
Text("START OF PAGE ------- -----Page Number: \(page)! This is a very short text made big to simulate scrolling. This is a very short text made big to simulate scrolling. ").font(.system(size: 90))
}
}
}
})
}
Am I missing something simple, is it a bug (with workaround), am I using these views wrong?
Ultimately I just want to have something that look like a page that you swipe right left or right but having the scroll position reset so fast would not be great user experience and doesn't look great
Edit: I haven't found any solution yet, but an interesting point: if I put the ProgressView inside the scrollView the scrollview does NOT reset position but the next tab will already be scrolled with the same amount as the previews page. This is equally "bad" if not worse :-(.
Try to put it into separated view (passing all needed parameters), so SwiftUI will see that view not changed and so not rerender it, ie. it should look like
if(coreData.pageList[page] == nil) {
ProgressView().onAppear(perform: {
loadPage(page: page)
})
} else {
DetailsView(page: page) // << ScrollView inside
}

how to make a view scroll with the collection view using swift

I have a collection view inside of UIViewController. The view controller also has another UIView (let's call it welcomeView) which is placed above the collection view. When I scroll through the collection view, I would like the welcomeView to scroll with it. I have looked at this answer https://stackoverflow.com/a/43215801/5124961 which pretty much sums up how id like it to look, minus the view sticking to the top. The only problem with that solution is that my collectionView already has a header, so adding the welcomeView as a sublayer to collection view adds it under the already existing header which I dont want.
by just using this snippet of code:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = collectionView.contentOffset.y
if(offset > 0){
self.welcomeView.frame = CGRect(x: 0, y: -offset, width: self.view.bounds.size.width, height: 100)
}else{
self.welcomeView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 100)
}
}
I get this effect:
I think the frame of the collection view has to change depending on the offset but not too sure on how to achieve this after playing around with it. I have also looked at a few other questions similar to mine, however, these were in objective C which I am not too familiar with. Does anyone have a solution? thank you.
If I guess correctly from your capture, your welcome view doesn't overlay the collection view.
Based on this guess, the solution would be:
make the collection view go to the top of your controller's view
your welcome view can overlap your collection view
to avoid that the welcome view overlaps the content of your collection view, modify the contentInset property of your collection view (the contentInset's top should be equal to the welcome view's height).
keep your snippet
the scroll indicator will probably disappear under the welcome view. A simple solution is to have a transparent background to the welcome view. Thanks to the contentInset and the delegate call, you're guaranteed that there's no overlap between the content of the collection view and the welcome view.

How to make a pop over view automatically adjust to its content size?

I subclassed a UIViewController to present it as a pop over on iPhone using its popoverPresentationController.
The view controller's view contains only a UILabel that is added using auto layout constraints.
The presented pop over is much larger than the label. I want the pop over to be only as large as necessary to fit its content. I tried by overriding preferredContentSize but that didn't work:
override var preferredContentSize: CGSize {
get {
label.sizeToFit()
view.sizeToFit()
return view.bounds.size
}
set {}
}
How can I make sure the pop over automatically resizes to its content?

Swift 3: UISearchBar in Popover ViewController shows up wider than expected (on iPad)

I have a view controller opened from a Popover segue - on iPhone displays this opens as a full page view controller (basically modally). On iPad it opens as a popover.
When opening the view on iPad the seachbar renders wider than the view of the popover. This does not occur on any of the iPhone screen sizes - Only iPad (as a Popover).
If I bring the UISearchBar to focus (tap on the textfield) the issue resolves itself until the view is opened again:
The UISearchBar is added programatically to a UIView of the desired dimensions.
Here is the code for initializing the SearchController
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.definesPresentationContext = false;
searchBarView.addSubview(controller.searchBar)
return controller
})()
I have tried removing .sizeToFit() and instead sizing based on a CGSize
controller.searchBar.sizeThatFits(CGSize(width: 375, height: 44)
This did not work however. I have also tried calling view.setNeedsLayout() and view.LayoutIfNeeded(). Neither of these have any effect.
I could solve this problem by making the UISearchBar active in viewDidLoad but am looking for a less janky solution.
Thanks!
Well this was an interesting lesson in debugging UI issues.
I believe this was ultimately caused by the ViewController being set to size inferred and size fixed. On different iPad screen sizes (9.7" vs 12.9").
To resolve this I set the frame width of the search bar to the tableview below it. I'm not sure why the searchbarview size changed width since its constrained to leading and trailing edges (superview).
if UIDevice.current.userInterfaceIdiom == .pad {
self.resultSearchController.searchBar.frame = CGRect(x: 0, y: 0, width: Int(tableView.frame.width), height: 44)
}
Although this works it has the same issue if split view is used (for widths where a popover has room to display).
Further suggestions are welcome but this is a good start.
---Edit---
Unchecking "Resize View from NIB" under layout in the ViewController as well as setting size to Freeform and declaring a constant width resolved the issue of the VC resizing on iPad. From there I just set the frame of the search bar in viewDidLoad as follows:
if UIDevice.current.userInterfaceIdiom == .pad {
self.resultSearchController.searchBar.frame = CGRect(x: 0, y: 0, width: 375, height: 44)
}
Seems to work for all devices regardless of split view or not. There probably is a better way to do this without detecting iPads. Im thinking I'm missing a setting in Interface Builder.