I guess this question is more of a best practice question than a problem solving question.
I would like to have a page on my app that has a UITableView at the bottom of it and some buttons/text above the UITableView but instead of just the UITableView scrolling, I would like the whole page to scroll.
I have been searching around and some people say to put the UITableView inside of a UIScrollView and disable scrolling on it and recalculate the height so the table view is as tall as all of it's rows.
Then I have read some other people say just to put the buttons/text in a Table Row Header and just have that scroll with the whole table view.
Which is the better practice and are either of them frowned upon?
Thanks!
Open the main storyboard and on the bottom right hand side you should see a list of view controllers, buttons, gestures etc.. In that list there should be a controller called "page control" that opts for the page-scroll you are looking for as well as the continuous one which you are trying to get rid of, you can just insertt this in to your basic view controller (via drag and drop). As for the button responsible for the segue (turning the page) you can find that in the list too. I can't explain how to program the button to turn the page step by step as I am typing this on my phone at work right now. If you want I can edit this later in more detail
Related
New to Swift. I am trying to write a recipe-sharing app for fun. One of the features is to let users create a new recipe. On this page, users should be able to give an intro to the recipe to be created, upload an image THEN add a LIST of ingredients dynamically (as we have no idea how many ingredients in total beforehand).
I have created a UIViewController, which includes a UIViewTable, an image view and a "add another ingredient" button. I have created a class for the ingredient. And when the "add" button is pressed, a new "Ingredient" cell will be added to the table. However, I found that adjusting the UIViewTable height dynamically is quite hard.
I want my table to adjust its height according to the number of cells (rows). I haven't found much useful info online.
Or maybe I should've not even used this structure. Instead, just use UITableController (The entire page is a table)? But I got confused that some of the elements (image view, submit a recipe button, recipe-intro textfield etc) will be only created once. Why do I bother making them as prototype cells and add them to my view programmatically?
Thanks in advance!
First of all, welcome to Swift!
You put a few questions together, I will try to answer them one by one. Let's start with the simple stuff.
Don't try to change the height of UITableView based on the number of items. If you want to achieve similar functionality, take a look at UIStackView. Set fixed size for the tableView, ideally with constraints using auto layout.
UITableView is supposed to fill specified space and scroll items inside or show cell on top if there are not enough cells to cover all space.
UITableView is highly optimized to scroll over huge amount of cells as the cells are reused on the background. If you are new to the iOS world, take a look at this function https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse it can save you hours of debugging (I have been there)
UITableView vs UITableController
UITableController can save you a few lines of code, but using UITableView inside of UIViewController can give you more freedom and save you refactoring if your app is likely to change in the future. There is no specific advantage of UITableController
If you want to provide the extra elements (image view, submit button, text field etc), you can use several methods and this is where the UIViewController with your own UITableView comes in handy.
You can put some buttons, like a plus icon or "Done" button into the navigation bar, as the native Calendar app does.
You can put the static content (intro text field, image view) above the table view (visible always). Use constraints to place the static content on the viewController.view and constraint the table view under your static content. The table view will take less space on the view keeping the space for your content.
Insert your static content as a table view header (will scroll out with the content). Search "HeaderView" here on stack overflow to see how to achieve that.
Place your content over the tableView. If your button is small (rounded), you can place it over the tableView, eg. Twitter uses this for a new tween button.
Hope this answer your questions. Cheers!
I'm currently creating an update of my iOS application and I'm a bit stuck. I've tried to googling around but cannot find a decent answer on this.
I've a menu which links to different views. And I'm not really sure if I've done it the best method.
I've created a view, and added the links into a stack view. Should I considering changing it all to a tableview? or a collection view? Or maybe there's another way?
The current look:
Should I change this to a tableview? collection view? or something else? Or just let it stay as it is?
If the number of items in your menu changes at runtime and is large, you should use a table view, because a table view is good for efficiently displaying a screen's worth of items from a large list of items.
If the contents of your menu is small (under maybe two screenfuls of items) and fixed at compile time and you are using a storyboard, then you could use a table view with static cells, if you can make it look the way you want.
If the contents of your menu is small, then you can use a stack view (inside a scroll view) if that is easier for you. There is no particular advantage to using a table view over a stack view to display a small amount of content, unless you need other features of the table view (like the ability to select/deselect rows).
Based on the screen shot you posted, I'd either use a table view with static cells (since the screen shot is from a storyboard) or a stack view, depending on whether I can get the appearance I want from a table view. If, as in the screen shot, the buttons must be centered vertically, I'd use a stack view, because it's easier to vertically center the content with a stack view.
Look, the fact of have many itens on your screen is clear on the mobile applications, to make it easy, we have collecions view like UITableView and UICollectionView. On the UITableView's case, this implements the scrolling and have methods do handle the operations' list, you can see the documentation to check these methods: https://developer.apple.com/documentation/uikit/uitableview.
Main reasons to use UITableView
Implements scroll behavior.
Independent of size screen you can access all itens.
Easy to detect interactions like tap on cell.
Easy to make changes, like insert and remove content.
The UITableView exists precisely to solve problems like you has.
I am writing a Swift app, and on my main screen I have a long scrollview with several regions of content in it (upcoming events, announcements, and then featured products, and finally some basic info). So it's this really long scroll, and you can swipe down to the bottom.
So visualize 4 boxes, if you will, stacked vertically.
The 3rd box shows featured products. This can be anywhere from 1 to 30 items, depending upon any filters the user has in their settings.
My first try was using a UITableView for region#3 inside of this parent scrollview, but the problem is it only shows the first few items/rows and then the rest you scroll inside the table (which is the default/natural behavior of a table, right?). Unfortunately, the requirement I have is that the inner table can't scroll - it needs to display everything at once and you have to scroll (in the main UIScrollView) to get to the bottom (not scroll inside the inner uitableview scroll). Also, everyone seems to say don't use UITableView inside of a scroll.
So how do I create some sort of list where I create one template (like how you would in a xib/tablecell, and then assign a data source to it, and then repeat down without scrolling? Should I use a tableview after all, and just make the height of it very high and turn scrolling off?
Do I somehow instantiate xibs in a for loop and assign them dynamically to some view?
Thanks so much!
Sounds like you want a Table View with Grouped style. That would make it fairly easy to keep your "4 boxes" segregated, and your "3rd box" would simply be 1 to 30 rows in that section.
On note: you don't want to have a "very tall" table view - or any other type of view, for that matter. You want to allow iOS to manage memory for you, and to load and display only those parts of your content that is visible at any one time.
In other words, use a table view like its designed to be used :)
This is related to this question
ios filter options similar to the apple store (dropdown list)
I tried using a uitableviewcontroller instead of a pickerview as I couldn't understand how to use the picker view if I need it popping out (any info on it would be appreciated).
Now this is what I did.
I have a VC that calls out a "FilterVC". I only have one FilterVC that is called by 3 different "filter buttons", and I will just populate the VC depending on the button. The issue is, one button might have just 2 items that is needed to be shown, another one might containg up to 50. Was wondering how do I adjust the height of the popovercontroller that contains the uitableview? Also, is this the right way in dealing with popovers, 3 segues connected to one VC??? (It needed an anchor point)
Here's what it looks like
As a follow up question:
Is this the right way to do it on an ipad? I feel like most people prefer the uipicker. The guy that answered my first question said it's more of a design thing. Now since I'm no designer, as a user, do you think uitableview is more appealing?
Thanks for your time!!
In the view that you're showing in the popover, set self.contentSizeForViewInPopover as soon as you know the size and before the view is displayed.
The main benefit of using a table view over a picker is that it has a scroll indicator so you can see how long the list of options is. Also obviously that you can control exactly how the list is displayed. So the table view should be better if it fits in with your UI style and particularly if the list of options is long.
I am trying to achieve the following effect:
A UICollectionView displays a grid of cells for a parent type of object, e. g. a photo album. When I tap one of these items, I would like to scroll that element to the top of the screen and open a Springboard like folder from it. Inside that folders area, another collection should be shown, consisting of the detail items, i. e. the individual photos of that album. Tapping in the remaining "parent" view closes the folder again. See this schema:
What I have done so far is a regular collection view for the albums. When I select one, it scrolls to selected item to the top and then uses JWFolders to open an empty folder at that place. Once that is shown, I trigger the surrounding UINavigationController to push my 2nd view controller with the detail items. That one is layed out so it appears to the user as if it were still the same view.
There are several problems with this approach, and I would like to know how to do this better:
JWFolders takes a screenshot and animated two halves of it up/downwards to achieve the opening effect. This is ok, but pretty slow on an iPad3, because it moves a lot of pixels and the iPad3's GPU is not quite up to the task.
The 2nd view needs to be pixel-perfect to match on top of the first one. This is likely to break accidentally.
I am limited as to what animations are possible for the view controller transition. The default UINavigationController's push from the right is not fitting. I override that to do a cross-dissolve, but still it is far from ideal.
I would like to get pointers as to how to approach this problem in a maintainable manner that does not require to much creative hacking against what the frameworks are designed to do. I might be missing something obvious here, so pointers to examples or general advice are appreciated.
Update:
I changed the approach a bit. Now I use a container view controller that has two embedded collection view controllers. One for the "Album" and one for the "Photos" part at the bottom. Using a UIImageView in the middle between the two I can get the triangle pointing upward done. This is also nice from a maintenance point of view, because it makes maintenance easier with the two collections being handled completely separately.
The app uses Auto Layout, so I can change the amount of space each of the two embedded views takes by modifying the constraints. This is way faster than the screenshot based approach with JWFolders and works nicely on an iPad3 as well.
This almost gets me where I want to be. The one thing that remains is to get the opening animation right. I would like to simultaneously scroll the Albums collection, so that the tapped item goes to the top and expand the photos collection with the triangle pointing at the Album cell.
Can I somehow "connect" the lower view to that cell via layout constraints, so that the scrollToItemAtIndexPath:atScrollPosition:animated: call drags the lower view open?
To get around it I would lose the library and cause iOS to move those display elements around without screenshots or other tricks. On the tap, cause the tapped icon to retain its normal appearance while you dim all the others. Find the contents of the collection view from the top to the end of the line where the tapped icon is. Create two new collection views - one which contains the top half, including your tapped icon and one containing the rest, below. Animate those views apart to make room for the folder view.
The folder view is another UICollectionView that appears in the gap created.
In the main view there are either one or three views presented depending on whether the drawer is open or closed. I would probably look at creating a view controller with a collection view, and using view controller containment to manage all three views. You have complete control over how those views are presented, so you could animate top and bottom views up and down simultaneously to reveal the folder view in place, as Springboard does.
When that's all working then you could generalize and start doing things like deciding to make the tapped icon part of the bottom collection with the folder appearing above if the icon was low on the screen.
(I hesitate to answer this because of the large number of upvotes yet no answers, so I may have missed something - but that is how I would begin trying to achieve the Springboard effect.)
To solve this problem in a relatively easy way, you could try to make the folder a simple UICollectionView subclass and then insert that cell when the albums cell is tapped.
In the collection views data source you would have to return different size etc. for the folder cell.
In the folder you would have to create the folders collection view, avoid making the folder cell the data source of the cell folder collection view tho.