Please help! :) Im a huge noobie here. I\'ve gathered this code from various sources so i don\'t really know what I\'m doing. My alert controller displays a textfield that I can
Although I found a way to scroll to the top of UIAlertController actions,
I don't recommend doing this, because I don't know if your app would get rejected.
I think this answer is only relevant for iOS 10+
self.present(alert, animated: true, completion: {
//print(alert.view) // _UIAlertControllerView
//print(alert.view.subviews) // [UIView]
//print(alert.view.subviews[0].subviews) // [_UIAlertControllerInterfaceActionGroupView]
//print(alert.view.subviews[0].subviews[0].subviews) // [_UIDimmingKnockoutBackdropView, UIView]
//print(alert.view.subviews[0].subviews[0].subviews[0].subviews) // [UIView, UIVisualEffectView]
//print(alert.view.subviews[0].subviews[0].subviews[1].subviews) // [_UIInterfaceActionGroupHeaderScrollView, _UIInterfaceActionItemSeparatorView_iOS, _UIInterfaceActionRepresentationsSequenceView]
// _UIInterfaceActionRepresentationsSequenceView <- This is what we want
// In this view are all your added actions. It is a subview of UIScrollView, so just cast it and set the contentOffset to zero
if let scrollView = alert.view.subviews[0].subviews[0].subviews[1].subviews[2] as? UIScrollView {
scrollView.setContentOffset(.zero, animated: true)
}
})
This may not work sometime, because I don't check if the subviews are in this order.
A future iOS update could also completely crash this method.
Also I just tested this on an iPhone. I don't know if it works on an iPad.
A more or less safe way (suggestions welcome):
self.present(alert, animated: true, completion: {
guard alert.view.subviews.count >= 1 else { return }
guard alert.view.subviews[0].subviews.count >= 1 else { return }
guard alert.view.subviews[0].subviews[0].subviews.count >= 2 else { return }
guard alert.view.subviews[0].subviews[0].subviews[1].subviews.count >= 3 else { return }
if let scrollView = alert.view.subviews[0].subviews[0].subviews[1].subviews[2] as? UIScrollView {
scrollView.setContentOffset(.zero, animated: true)
}
})
This finds the scrollView and scrolls to the top. We search all subviews because more than one subview responds to setContentOffset, but don't bother checking which one.
- (void)methodThatCreatesTheAlertController
{
// make the alertController here, add actions, and then...
[self presentViewController:alertController animated:YES completion:^{
[self scrollToTopOfAlertControllerView:alertController.view];
}];
}
- (void)scrollToTopOfAlertControllerView:(UIView *)view
{
for ( UIView *aSubview in view.subviews ) {
if ( [aSubview respondsToSelector:@selector(setContentOffset:animated:)] ) {
// _UIInterfaceActionGroupHeaderScrollView
// _UIInterfaceActionRepresentationsSequenceView <-- this is the one that scrolls
[((UIScrollView *)aSubview) setContentOffset:CGPointZero animated:YES];
}
[self scrollToTopOfAlertControllerView:aSubview]; // recurse
}
}
set your alertcontroller class with this code
https://gist.github.com/petrpavlik/0c5feaada5913cafde8a