MSStickerBrowserView stickers going out of frame - ios

I am attempting to dynamically load stickers for a Messages Extension for iOS 10. I have successfully loaded these icons; however, they fail to properly constrain to the proportions of a message app.
In the compact view of a message extension, it has a footer. This can be seen here:
In the expanded view of a message extension, it has a header.
I am loading these stickers through a MSStickerBrowserView a subview of MSStickerBrowserView. I'm overriding the superclass methods of numberOfStickers and stickerBrowserView to load my images.
From what I can tell, the MSStickerBrowserView is just a wrapper for a UICollectionView.
Anyhow, after the stickers are loaded they are not being constrained to the header and footer. I've attached a gif of what I mean below:
As you can see, in the compact view the last row of stickers go under the footer. Accordingly, in the expanded view the top row of stickers go under the header.
As an experiment, I implemented the same dynamic sticker system but with an actual UICollectionViewController and UICollectionView (instead of the MSStickerBrowser wrappers) and the same effect was achieved. Further more, I attempted to create a custom layout for this but it produced the same result.
I would prefer to stick to the MSStickerBrowserView, since it was already made for this purpose; however, if you see the UICollectionView more fitting I would be willing to change.
Note that with the use of the MSStickerBrowserViewController and View, the UICollectionView seems to be created programatically, so storyboard constraints are not available and I have not been able to apply any programatic constrants to the cells of the views.
I'm not really sure how to fix this, and would love any suggestions.

The way I fixed this was to use a UICollectionViewController with a state variable to represent the current presentation style (.expanded or .compact) which I set at presentation time.
Then in viewWillAppear for my UICollectionViewController, I set the collectionView's contentInset depending on the presentation style
if let style = self.presentationStyle, style == .expanded {
collectionView?.contentInset = UIEdgeInsets(top: 95, left: cellPadding, bottom: cellPadding, right: cellPadding)
}
cellPadding is a number I've computed after setting the itemSize in my collectionViewLayout but the value of 95 is just a guesstimate/kludge as I haven't yet found out how to get the size of the containing iMessage top nav bar.

Try Uncheck below options for your view controller:
Under Top Bars
Hope it will work....

You can try using storyboard to layout view and add a empty view under the browserView to solve

Related

Swift: TableViewController in NavigationController - Change distance between first static cell and top

Ive created just a new xcode project without any coding. I just worked in the storyboard. There I have a Navigation Controller. My RootViewController has a TableView with Static cells in 3 sections (Grouped). The Section headers I deleted. My next step was to change the distances between the sections. For top I said 4 and for bottom 4, too. It looks now like this:
Now my problem: The size between the first section and the top is really big (I think 32 because thats the automatic distance between the sections). THe only place I found something was the size inspector - Content Insets. This is set to automatic. With no option I can put some values in myself. If I choose never there, the section got displayed under the Root View Controller header. My size inspector looks like this:
Can anyone tell me how I can reduce the size between viewController top and first section? Exactly I want to have a size of 16 between first section and the header of the Root View Controller.
And is there a way to do a change for the complete project so that also upcoming navigation controllers will have their tableview with a size of 16 between first section and the header?
What Ive tried: I found this question Why is there extra padding at the top of my UITableView with style UITableViewStyleGrouped in iOS7 Here someone asked for tableViews in general. The solutions I readed there which didnt worked for me:
Turn Adjust scroll view insets off. I tried this for the root as well as the navigation controller. I also tried to solve the problem in code.
Set edgesForExtendedLayout to none in viewDidLoad - nothing changed.
Set the header just for first section to 1.
self.navigationController?.navigationBar.isTranslucent = true changed nothing
Half correct: One solution was changing the contenInset manually in code. I dont like this because I would have to type the 16 points hard in my code. I dont know there the header of 32 comes from. So I dont know if the 16 points will stay forever. So I want a safer solution for future as well. THis was the hard solution:
self.tableView.contentInset = UIEdgeInsetsMake(-16, 0, 0, 0)
That top space comes from grouped style tableView header. You can add your own table header view at top of the table, set its color to "Group Table View Background Color", and set its height to what you want (16).
iOS11 Pure code Solution
Anyone looking to do this in pure code and remove the 35px empty space needs to add a tableHeaderView to their tableView - it appears having it as nil just sets it as default sizing of 35px
i.e.
tableView.tableHeaderView = tableHeaderView
var tableHeaderView:UIView = {
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: tableView.bounds.width, height: CGFloat.leastNormalMagnitude)
return view
}()
Note device width would be your bounds/view width and height is NOT 0 - but CGFloat.leastNormalMagnitude

How to set static grouped TableView cell's width

I am relatively new to Xcode and Swift development and I have a question regarding a UITableViewController with static, grouped cells (on iPad). I want a natural solution to make the cell width not as big as the whole screen.
I have tried this:
override func viewDidAppear(_ animated: Bool) {
tableView.frame = CGRect(x: 175, y: 70, width: view.bounds.width-350, height: view.bounds.height)
}
Problem is that this looks really nasty and gets tricky with navigationbars and tabbars at the top and bottom, but especailly doesn't work properly because it is set at viewDidAppear, so when using the swipe back gesture (like in Settings), the view still appears at full width for a second.
Do you know some other way to solve this issue? Maybe some autolayout stuff, i don't know, I've tried everything I know...
Any help will be appreciated! Thank you!
As you say, autolayout is probably the way to go. If you are using Interface Builder, then you can just set your constraints there. Plenty of information out there to help with that. Here's a good place to start: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithConstraintsinInterfaceBuidler.html
You should switch to using a regular UIViewController and manually add a UITableView as a subview of the root view. You'll also have to manually set the view controller as the delegate and dataSource of the table view. Then you'll be able to position the table view wherever you like. Unfortunately, you won't be able have static cells - but setting your data dynamically tends to be a better choice in the long run anyway.
The other way to achieve what you want and still use a UITableViewController is by setting it as a child view controller, but this is more fiddly and tends to be more restrictive in my experience.
If you want to manually set frames as in your code example, then you should do that inside the viewDidLayoutSubviews method.

hide/ show controls in View controllers

My application gathers input from users and hence it is full of Labels, text boxes and buttons and I have to show or hide set of labels and text boxes based on certain conditions.
To accomplish it, I did the following.
Set fixed height (lets say 30) for all the controls
Set height constraint on each of the controls and created an outlet to the height constraint in the ViewController
Alter the heightConstraint.constant value programatically (between 0.0 and 30.0) based on the scenarios.
Having programmed like this, it is very difficult for me if there is any change in layout. (i.e., if user requested to add/remove any particular control from the view Controller).
I am using Auto Layout constraints. Could anyone suggest if there is a better way to accomplish my goal.
I am using IOS9 and Swift.
Many thanks in advance.
You can use UITableViewController with static cells for this case.
For hide/show row or section, you can change the size in the tableView:heightForRowAtIndexPath method.
UITableViewController automatically manages the layout and with static cell you can even create outlet for all the controls.
Have you considered using a table for this? It has mechanisms for inserting and deleting rows and would manage the layouting for you - only part you'd need to care about are the contents of the cells.
Instead of making IBOutlets to the height constraints of all the views that you might need to hide, you can just use the hidden property of UIViews to hide/show the view.
In case you need the view to make space for other views, you could set a simple animation and move the view out of screen bounds. You might face issues with layout constraints but it's surely worth the effort from a UI/UX perspective.
Additionally, if you know that you don't need a view any more you can even remove the view from it's superview.

How can I get the correct sizes for UIViews created in storyboard during runtime

I created a UIView using storyboard, set up constraints. When I ran the application, the interface looked fine. The view covered the entire screen as it was supposed to (I made the background color black so it's easier to see what's going on).
http://contentlibrary.sinaapp.com/View%20from%20Storyboard.png (I'm sorry I have to link images in like this, but the system says I need at least 10 rep to post images.)
However, when I tried to get the size of that view using myView.bounds.size. I got (600, 580), which is exactly the size that appeared in the storyboard's size inspector.
I created another UIView in code
var myView = UIView(frame: CGRect(x: 0, y: 20, width: 600, height: 580))
and added it as a subview to the top-level view. It appeared but it didn't cover the entire screen like the view I created in storyboard. Both the view I created in storyboard and in code have the same value in their .bounds.size, but they appeared to have very different sizes on screen. (This picture is the view created in code. See there is white space at the bottom of the screen.)
http://contentlibrary.sinaapp.com/View%20from%20Code.png
Another interesting thing is, if I replace the above UIView with a UIScrollView, after the scroll view zoomed, it will update to the correct size.
I added a UIScrollView the same way I added the UIView using storyboard. I tried to print its size inside the delegate method scrollViewDidEndZooming:withView:atScale:. It says (375.0, 647.0), which is the correct on-screen size for a view that covers the entire screen on an iPhone 6.
Judging from this, it seems that views that come out of a storyboard don't automatically update to the correct on-screen sizes.
So how do I get a UIView object created in a storyboard to update its size?
Sounds like you're checking the size too early.
Try to put your code in viewDidLayoutSubviews method and see if it's going to change.

Creating a fixed footer in viewport in iOS

I want to create a footer fixed to the bottom of the viewport in an iOS app I'm developing (it's my first one, I come from a web dev background). However I'm having difficulty finding information on how to go about this.
What I have in mind is essentially just 3 rectangular buttons next to each other that are just constantly fixed to the bottom of the viewport. I tried dragging a toolbar into my scene as a starting point, but in the interface builder it's placing itself under my table cell, rather than fixing to the bottom. I feel like this is probably easier to do programmatically, but I just don't know where to start.
If someone could at the very least guide me in the right direction I'd really appreciate it. Thank you.
Okay... create/add custom UIView on your main view (self.view)
and set this custom view's frame = (0, 0, 320 , self.view.frame.size.height - 50) /// change value 50 to as per your requirement.
and add all of then UIControls such like textField, tableVie, button ...etc.. on this custom view.
Don't use a UITableViewController. Use a UIViewController, then add a table view and a toolbar. You'll need to implement the UITableViewDelegate protocol in code and then connect the delegate in interface builder.

Resources