Center a scrollable InputAccessoryView - ios

All,
I have a scrollable InputAccessoryView attached to my UITextView.
This was created as follows:
create a UIScrollView
add a horizontal UIStackView.
Attach top, bottom, trailing, leading of stack view to scroll view.
Set equal heights between stack and scroll.
Insert lots of buttons into stack view.
set TextView.inputaccessoryview = scrollview.
Voila! (Note - only the last line was programmatic).
So this works fine and correctly scrolls when the content (stack view) is wider than keyboard, BUT when you rotate to landscape (or run on an iPad), it is left aligned.
I'd like the buttons to be centred when the keyboard is wider than the set of buttons.
I've tried embedding the Scrollview into a UIView with Center X, but that doesn't seem to work.
Can anyone give me some pointers?
Thx

Found it!
The answer is to use ContentInset on the scrollbar (which is the InputAccessoryView above). The specific code is:
public void CentreToolbar()
{
var offsetX = Math.Max((scrollView.Bounds.Width - scrollView.ContentSize.Width) / 2, 0);
scrollView.ContentInset = new UIEdgeInsets(0, (nfloat)offsetX, 0, 0);
}
This code should be called anytime the layout of the screen changes - such as during rotation.

Related

how to change direction of scrolling in UIScrollView?

I have a horizontal scroll view with fixed height .my scroll view, scrolls from left to right but I want to scroll from Right To Left . how can I achieve this?!
this is how I created my Horizontal scroll View:
I've scroll view leading and trailing align to parent, and height = 50, inside my scroll view there is a view with equal height and width to its parent, but the priority of equal width is low, so it can scroll horizontally!
the answer was in this link
I had to add these lines to my code in swift 4:
myScroll.transform = CGAffineTransform(rotationAngle: .pi);
subview.transform = CGAffineTransform(rotationAngle: .pi);

Unwanted white space on left of UIScrollView on iPhone X

UIScrollView works fine without the white space on the left on all iPads or iPhones except for iPhone X. How can I remove the white space?
I use storyboards. Bounce On Scroll/Zoom are all disabled. No white space on iPad or iPhone except for iPhone X. I think it might be something related to the Safe Area thing.
This spacing is from safe area, which is applied to left/right of UIScrollview as content insets in landscape orientation on iPhone X, which can be seen using read-only property UIScrollview.safeAreaInsets.
Following line can be used to get rid of safe area insets when you dont need:
UIScrollview.contentInsetAdjustmentBehavior = .never
The default value being UIScrollViewContentInsetAdjustmentBehavior.automatic includes safe area layout guide margins as content insets.
Note: auto layout constraints has nothing to do with the insets, its just iOS 11 UIScrollview content insets adjustment behavior.
Setting the constraint relative to safeArea is good practise for iPhone-X.
This is how apple says -
When the view is visible onscreen, this guide reflects the portion of
the view that is not covered by navigation bars, tab bars, toolbars,
and other ancestor views.
In your case you are giving constraints leading & trailing of scrollView with safeArea, Not superView
Hence if you take risk giving constraint to superview instead of safeArea your object content may clipped, specially when you rotate left, content from the left most will clip under top notch of iPhone-X.
Apple doc for safeAreaLayoutGuide
Well, I solved this issue in non-elegant way. But it works like a charm. (I tried all other answers. Thank for your help, however those answers don't seem to work in my case.)
var leftMargin: CGFloat = 0
var rightMargin: CGFloat = 0
if Device.isPhone() && Device.IS_5_8_INCHES() {
self.leftMargin = 44
self.rightMargin = 44
}
let frame = CGRect(
x: (self.view.frame.width - self.leftMargin - self.rightMargin) * CGFloat(pageIndex),
y: ...
)
Safe Area Layout is responsible for this white space.
1st Option:
Ignore safe area layout for your scrollview and set scrollview's constraints with respect to its super view (or main view). Scrollview automatically handle safe area inset for contents while scrolling.
Landscape View:
Portrait View:
2nd Option:
I do not recommend to remove/change safe area layout for your scroll view and an alternate solution that can solve white space visibility issue:
Set blue background color (that you've applied for your scroll view) to your main view of your view controller, if scroll view is covering entire screen.
set clear color background for your scroll view
Add this code in your viewDidLoad
# IBOutlet var scrollView: UIScrollView!
override func viewDidLoad(){
super.viewDidLoad()
self.view.backgroundColor = UIColor.yellow // set here blue color that you've applied for your scroll view
self.scrollView.backgroundColor = UIColor.clear
}
Here are good reference answers regarding Safe Area Layout, for better understanding:
Safe Area of Xcode 9
Use Safe Area Layout programmatically

UIScrollView Bounces To Either Top Or Bottom

I have a UIScrollView for which I have a UIView which is the subview of the scroll view , the UIView has a lot of other subviews and I am getting the height for it dynamically after adding the subviews , this is my piece of code to add the view to scroll view
CGRect frameOfView = CGRectMake(0, 0,Get_Bounds.width, globalYPosition);
self.parentProductDetailView = [[UIView alloc]initWithFrame:frameOfView];
I am first initialising the view this way and then after adding all subviews I am doing this,
frameOfView.size.height = globalYPosition;
[self.parentProductDetailView layoutSubviews];
self.parentProductDetailView.frame = frameOfView;
[self.productDetailScrollView addSubview:self.parentProductDetailView];
self.productDetailScrollView.contentSize = CGSizeMake(0, self.parentProductDetailView.frame.size.height *1);
But my scrollview does not scroll properly it either sticks to top or bottom.
Here globalYPosition is the sum of height of all subviews added to parentProductDetailView
The procedure you used seems correct. No matter the subviews your scroll view should scroll properly by simply using a larger content size then its frame size.
The scroll view may stick, snap to some points if paging is enabled which is what is happening in your case. If the content view is larger then 1.5th of the frame size then the scroll view will snap to top/bottom or left/right. If it is smaller then it will only snap to starting position.
This may be very useful for situations like having a side menu that takes a part of a screen but in your case you should simply disable the paging and scrolling should work fine.

Resize UIScrollView's height to screen height?

Black - screen frame/size
Red - default UIScrollView's frame/size
Yellow - my button.
I want to always keep that button at the bottom. So e.g. on 3.5in screen, scrolling is available and button is at the bottom, no problem. Now, when we move to 5.5in screen, it becomes like in this image, button is not at the bottom anymore. What I am trying to do is change UIScrollView's height, but it does not work:
if(self.view.frame.height > contentView.frame.height)
{
print("fixing scroll view")
contentView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height * 2)
scrollView.contentSize = CGSizeMake(self.view.frame.width, self.view.frame.height * 2)
}
self.view.frame.height * 2 is just for testing. What could be wrong?
Late response, but for those who need a button to stay at the bottom of the screen in a scrollview, if the content view should be the same as the screen height, try this:
Set ScrollView top, left, right and bottom constraints to 0 from parent
Set ContentView to Equal Width and Equal Height of ScrollView
Set ContentView top, left, right and bottom constraints to 0 from ScrollView
Give each element inside the scroll view some constraints, linking everything from top to bottom
Select one constraint between the elements and remove it, or make it low priority. I'd say to make it low priority because if you have to delete the Equal Height, the layout won't break.
With auto layout all you need to do is add pin constraints to your scrollView to each corner of the superview.
Set your 4 constraints to 0 and you'll be all set.

How to make uiscrollview only vertical scrolling for ios?

I'm trying to make layout inside scrollview using this one tutorial link
And get the following result link
It will be appreciated for any advices or tutorial links. It needs only vertical scrolling
I am sure there must be other ways to do this but a quick fix is :
1.) Create a width constraint on ContentView in Storyborad.
2.) IBOutlet that widthContraint and set its value to the view frame width in viewDidLoad.
Suppose the name of the constraint outlet is contentViewWidthContraint.
contentViewWidthContraint.constant = self.view.bounds.size.width;
Another alternative to do so from Storyboard, is to fix the Contentview width to the view's width from the storyboard or to the Scrollview, if Scrollview already has a Equal width contraint with superview . Add the "Equal Width" contraint from Contentview to either self.view or to Scrollview (if scrollview, already has the width contraint)
Have you set up the "ContentView" width to match with the scroll view width? I had the same problem and I fixed with "Equal Widths".
"Equal Widths" will tell to your "ContentView" to use the same width of the "Scroll View", which should be fitting the screen if you have set up the constrain properly.
You can do this easily on the storyboard.
Drag and drop, with right click (important!!!), from "ContentView" to "ScrollView"
Release the click, you will be prompted with a menu, select "Equal Widths".
This should fix your problem using the scrollview with AutoLayout from Storyboard editor.
You can find a full tutorial how to use ScrollView with Autolayout and Storyboard here.
I hope this is useful for you :)
In the Storyboard set the width of the elements contained in your UIScrollView equal to the width of this UIScrollView (by selecting all elements and the UIScrollView holding in the panel on the left of your Storyboard and then setting the 'Equal Widths' constraint under 'Pin' on the bottom of your Storyboard). Just pinning the right sides of the elements to that of the UIScrollView won't work as it will adjust the size of its "display view" to the width of the largest element and if this is smaller than the width of the UIScrollView all elements will just appear aligned to its left side.
There is also another possibility that offers a very good result.
You can mark a checkbox:
O programmatically:
scrollView.alwaysBounceVertical = true
Try to set it's width to 0 & height equal to content size like this:
self.scrollView.contentSize = CGSizeMake(0, self.scrollView.contentSize.height);
This will work as you want. Try it & tell if still facing any issue.
For disabling the horizontal scroll, you can set the content size in the -(void)scrollViewDidScroll method.
[self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];
self.scrollView.directionalLockEnabled = YES;
This is because scroll view have no idea where your content should end.
But when at least one item inside your scroll view has its "trailing space" constraint attached to a view outside the scroll view (usually a view the scroll view is sitting in or some other view of a higher level, which "knows" its width) - the scroll view will automatically get an idea about your wanted width and won't scroll horizontally (unless that trailing constraint implies having your content outside the screen).
Better if all items inside scroll view have their "trailing space" constraints connected either to each other or to a view outside the scroll view. But not the scroll view itself.
No additional code or extra constraints needed for this to work.
Too set UIScrollView constraints as like below code so it will occupied whole screen.Not exceed the screen size.
Leading Space = 0 from mainView
Top Space = 0 from mainView
Bottom Space = 0 from mainView
Trailing Space = 0 from mainView
You need to set the width of UIScrollView equal to or less than the width of your Parent View. Two ways to do it:
1) You can do this in Storyboard via layout constraints
2) You can do this programatically:
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.scrollView.contentSize.height);

Resources