Override hitTest SwiftUi? - swift

I have a transparent view on top of another view in a z stack and would like to interact with them both simultaneously. How can I override hit test in swiftui so I can interact with both views in the z stack on top of each other?
I found a way using ui kit but how can I do the same swiftui? How can I click a button behind a transparent UIView?
I tried changing both views zindex to 0 but doesn’t work as one view still cancels the other out. Any thoughts?
// I want both views to be interctable but shows that z layering
ZStack {
TestView()
MainView().allowsHitTesting(true) // I still want this view to be interactable
}

Related

UINavigationController weird transparency behaviour when presenting

I'm experiencing a weird glitch with the transparent navigation controller. When presenting a view controller with a UIImage at the top of the navigation controller: at first presents half of its background blur with a dark section, and half with a clear one; and after a very short moment it changes for a full dark background. As shown in the gif:
The UIImage displayed is mostly white, the borders are very close to pure white. So the grey color does not make much sense (less sense makes the rapid change).
I did disable extend edges under top bar in the Storyboard for the presented view controller. So the image is not hidden behind the Navigation Controller. With this option enabled the glitch does not appear, but I don't want to hide part of the image.
Disabling the transparency, solves my problem, but I'd like to be able to keep the transparency effect.
Edit: I did notice the "grey effect" also makes the navigation controller opaque. But only for that view, when going back, is transparent again.
Xcode 11, Swift 5, iOS 13.2, iPhone XS.
Thank you very much for your help.
I finally found the problem.
I didn't want the UIScrollView to bounce on top so I used this code:
extension ProblematicViewController: UIScrollViewDelegate {
/// Prevent bounce at top
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 {
scrollView.contentOffset.y = 0
}
}
}
Which meant the ViewController's Adjust Scroll View Insets were overwrite (I think). So my scroll view did lay under the UINavigationController, to prevent this from happening, I did disable Extend Edges: Under Top Bars, so the root UIView containing the UIScrollView was not covered by the UINavigationController. So the transparency effect could never happen because the view was never under the top bar. More about Adjust Scroll View Insets on this post (helped me to find the problem).
Removing those lines and enabling Adjust Scroll View Insets and Extend Edges: Under Top Bars, solves the glitch problem, but the UIViewController does not have the "prevent bounce on top" behaviour that I wanted.
This kinda explains the weird behaviour of the UINavigationController because the SO has to calculate a transparency over nothing, but is sill strange, the transparency effect is calculated when the ProblematicViewController is fully presented, and not on viewDidLoad() or another view's life cycle before is shown to the user, so the transition is smooth, even when nothing lays behind the effect.

Scroll View lightening background color

I am using the same background on different views in my app and remarked something strange with the only view where I use a UIScrollView: the background is lighter than expected.
Uninstalling the scroll view gives it its color back. I am 100% positive this comes from the scroll view only and not it's subviews because uninstalling anything (and everything) else inside the scroll view has no effect.
No scroll view:
Scroll view :
Is there any solution to fix that?

sending UIScrollView to Background

I'm midway of finishing my app. I noticed that one of my views needs extra vertical space so I need to add a UIScrollView. Yet when I add that scroll view it overlaps everything else in the view. In simple words if I need to get it to work properly I have to delete everything off the view , add the scroll view, and then re-add everything back! Is there anyway to send this scroll view to the background of the view? This is all the code that concerns the scroll view
#IBOutlet var scrollerForPOfFourBar: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
/* non related code here*/
scrollerForPOfFourBar.userInteractionEnabled = true
scrollerForPOfFourBar.self.contentSize = CGSizeMake(320, 400)
}
I'm assuming you're using Interface Builder since you marked your scrollView as an IBOutlet.
On the view list, on the left, the order of the views specifies their Z order, with the views at the bottom being the ones drawn on top (with the largest Z).
To move your scrollView to the back, drag it just underneath of the view, and drop it there.
Keep in mind that you will have to drag all the views you had in your view into the scrollView (the easiest is to do it in the views navigator as well), and you'll have to set up any Auto Layout constraints again, which will be a pain.
Are you just want to move scrollerForPOfFourBar to back? Try this:
self.view.sendSubviewToBack(scrollerForPOfFourBar)

UIScrollview with paging and interaction

I am trying to wrap my head around how this would work. I want to create a horizontal scrollview consisting of "tiles" that are added and that you can scroll through (paging). On each tile will be a main image and other various smaller images that will act as buttons and launch popovers and such. I understand that I can create my "tile" as a uiview subclass programmatically or in a viewcontroller which then can have it's view added to the main uiscrollview. My question is where do I detect touch events of the small button-like elements in each tile? Would the main viewcontroller that manages the scrollview be the one that would handle the touches of the subviews' subviews?
You would detect the touch events for your tiles in whatever view handler you have them in. Basically you would have one view with a scroll view on it, then you would create another view that would have your tiles, within the view that contains your tiles is where you would handle the touch events for them, but you will have to keep track of which "Page" you are on to know what actions should be performed.
This is the best example I have found on using the page controls.

Transparency for top UIView not working

In a UINavigationController I have a UITableView. I use a settings-button to allow users changing some table settings.
When the settings-button is tapped I push a new view onto the navigation stack.
This new view has the following view structure
-> UIView1 411 x 320 px (backgroundColor supposed to be transparent) !!!!
-->> UIView2 270 x 300 px (backgroundColor grey)
--->>> Screen elements
My problem is that I want UIView1 to be transparent so that the information behind is still visible. All my attempts, such as
setting the bg color to transparent
changing the alpha value
removing the Opaque indicator
have failed so far.
Any clues? most appreciated!
UINavigationController is not designed to allow "buried" view controllers to still be showing under the current visible view controller. (The iOS framework can actually unload the views of view controllers on the nav stack that aren't the current top item!)
So if you try to do it, it just won't work, or you'll have problems. (Same goes for modal view controllers on the iPhone -- even if you make the background transparent, the view you're pushing on top of will disappear.)
If you really want the old UI to still be visible underneath, consider presenting your new entire UI as a UIView placed over the current view (i.e. do [existingView addSubview:myNewView]).