(please forgive my english)
I'm new at IOS developing but I've a good skill on other programming languages (mainly c#).
I'm trying to develop a test app with a main window.
Inside that window there is a scrollview with fixed size. inside that scrollviewer there is a view containing some stacked couples of one TextField and one Label: I can't know - ad design time - how many "rows" of them I have to put into.
My problems is:
I can put on the view the first couple (a textfield and, next, a label). Label size can be one or several rows high ,so I've to set multiline and sizeToFit
How can I put the second couple (and so on) without overlap the existing labels..? I can't use a table because between rows there are other labels (title of section).
Do I have to calculate the height of each label and programmatically calculate where to draw the next? Is there a more efficient way?
I don't need code, please just some hints or some keyword to googling on.
Many thanks.
I don't see why you can't use a UITableView, you can set up cells with all the controls you need in it. Either way, using a UITableview won't make the job any easier (just more memory efficient if you have many rows).
The only way that I see is, as you said, to calculate where the next 'row' should be placed (depending on the height of your previous rows). You'll also need to calculate the entire height, in order to set it to the contentSize of the UIScrollView.
Instead of UILabel you can also use a non editable UITextView, since it'll be easier to get its size (after you set the text, you can set the size of a UITextView to be equal to its contentSize)
Related
I am building an app about meetings where I want to show a preview of the VIP participants in each meeting cell.
These participants are not clickable nor scrollable, the only purpose it's to quickly see them at a glance.
The problem is that the view is very dynamic:
VIP's appear with image or initials
The rest of the attendees is just a number
if >5 VIP's, the circles start going together overlapping (spacing goes smaller)
if 9 VIPs, big wrapping circle “All VIPs in Attendance"
This is how it will look:
What should I do?
CollectionView (seems over-kill as I am not interested in any kind of interaction with the images)?
StackView?
Images (and change constrains programmatically)?
NOTE:
These is just one kind of Table View Cell, but we have a lot more variations, so we are building the custom cells in xib files. Xcode doesn't allow me to add a Collection View Cell in to the Collection View within the xib.
Interesting task - I'm sure there are numerous approaches, but here is one using UIStackView plus some on-the-fly calculations.
The idea is to define a maximum gap between views; a maximum width for all views; calculate the actual gap needed, and then let UIStackview handle the actual positioning.
Certainly not every feature you need, but should get you going in the right direction.
You can see/download the source for this here: https://github.com/DonMag/ScratchPad
Look at the Swift3/SpreadingViews sub-project for this example.
The problem with scrollable views (UIScrollView based views as UICollectionView), is that you will have to deal with the scroll, or pre-compute the width of your content, which is not always easy. For this reason, if you don't want to have scrollable content, I'd not use a UICollectionView, neither any UIScrollView based view.
Then you have the option to go with an UIStackView. Stack views are great to "append" multiple views and create some kind of "pile" of views in a very easy way. However, if you don't control how many items you need, you will overpass the boundaries of your container view.
Therefore, this is what I'd do:
"Fixed container view width" case: If your container view (your cell) has a fixed width (that never changes), I'd manually add as many UIImageViews I want to support in the XIB itself, and then hide/unhide them depending on the number of items I want to display.
"Variable container view width" case: If your container view (your cell) has a variable width (that changes depending on the screen size or whatever other factor), then you will have to compute in any case (do the math!) the amount of items you are able to display within the width you have available. Then, you can choose between using an UIStackView or adding your views & constraints manually to your container view.
Does what I say make sense?
Thanks,
I've been doing iOS for a while now, but when it comes to dynamically hiding / showing elements, I'm a bit lost.
Coming from Android, I'm used to being able to simply set views to visibility gone, but this doesn't exist on iOS.
So let's say I have the following scenario:
Basically I want to have a table, but the table should not fill the entire view controller. Instead it should leave place for optionally either a button, a multiline label, or possibly both at the bottom (if visible, these should be fixed, not scroll).
One way to solve this would be to use auto layout and modify constraints, like adding a zero height constraint. But that would make iOS kill one of the other constraints, which would make it hard to change it again. For the label, I wouldn't always want to have a height constraint, because it could be multiline, and should take the size it needs.
Maybe it's easier to skip autolayout here and modify frames instead, I don't know.
My question is: What approach would be best here?
Is there some other way of doing this I haven't thought of, or do I have to try to do what I described above?
I'm not primarily looking for code (code can be ok), but I'm more interested in a description of how it can be done.
I'd like to support iOS 7.
This problem had a variety of solutions, and opinion based, but I'm facing such questions a lot, when I don't know what to choose and what would be the "right thing".
So, I my opinion, the best solution here is using autolayout, you need to set height of label manually, but you have a few methods for this, at least you can play with it and if you don't succeed ask question about it. Using frames, you'll face same problem of calculating height, right? But with auto layout, you only need to set height, vertical space to 0, when you need to hide message.
You can also use constrains with priority lower 1000, and remove completely constraints from message (button, label) if you don't need it at all anymore.
For example, taking your layout image, you can make UIView with subviews: button, label. Top constraint connect to the UITableView, other constraints to the sides.Label and button will calculate the view's height. The only question here is label height.
So in ios assuming that the background of both these objects is opaque only the front most view in the Heirarchy will be visible and interactable, An easy solution would be to change the different frames of these two things you need and make sure they are in the back of your view heirachy, and when you need them to appear use view.bringSubviewToFront(mySubview) and view.pushSubviewToBack(mySubview) to make it disappear again. View obviously would be referring to main view of your view controller.
This is the most complicated UI related problem I've come across yet. I've been trying to find a solution for literally weeks but no avail. Let em explain.
In this app I'm working on, I need to display a certain list. It's actually a schedule. Here's how it should look like,
The fields circled by red circles don't change. To explain what change means I have to show you this.
Its a set of filters which the user can show/hide certain fields and the ones that are circled in the first image are static ones. They can't be toggled on and off.
Now the problem arises with the ones that can be toggled. Here's what it looks like if you turn off the Show Actions flag.
A new label with a blue background replaces the bottom one you can see in the first image.
Here's another one where you disable Show Time option and the time labels are gone (yes it affects only for some. Its expected).
If this filter list were an option list, it would have been easy. Just create a custom cell for each option and you're good to go. But unfortunately the user is able to toggle multiple filters! For example the user can turn off both Show Actions and Show Time and it'd look like the last image but the bottom label would have the blue label in the third image.
To top it all off, the cells' height is dynamic. In iOS 8 creating self resizing cells are easy enough from the IB when you could just add auto layout constraints and done.
But it seems to me that creating these cells from the IB isn't an available option to me. Simply because there are way too many filter combinations a user can make. So the cell's subviews need to adjust to it.
My question is how can I create a dynamic cell like that? My best guess is through code, right? I haven't written my UI in code before so I tried creating a test project to familiarize myself with it. But the problems I'm facing is setting fixed frame sizes makes the dynamic nature obsolete. And how can I move a view to fill up a removed view's space (Last image. Time labels are gone so the name and the id labels move to the left to fill that space).
I know this question is a little too broad. I'm not asking for a straight answer either. I'd really appreciate some pointers, or even a better suggestion on how to approach this because I'm truly at the rock bottom on this issue.
Thank you.
It's hard to give you any precise help since your question is so broad. First, I would recommend watching the 3 videos on Auto Layout from the WWDC 2012 (sessions 202, 228, and 232).
To answer your one example, how to move a view to replace a view that's removed. You would need to make two left edge constraints from the view with the text (Kund Alof...). One with a constant of 0 to the time label with a priority of 1000 (that's the default), and another to the left edge of the cell, also with a constant of 0, but with a lower priority, say 900. As long as the time label is present, the constraint to it will determine the position of the text label, but when it's removed, the lower priority constraint to the left edge will take over and move the label over to the left edge.
I am trying to create a table to show posts by users with possibly variable lengths. I want each cell in my table to resize to fit the content of the UILabel containing the text of the post. Currently I am doing this with auto-layout, programmatically setting constraints and calculating the height of the table view cell based on the height of the UILabel. Everything looks as I want it to, except when rapidly scrolling through the table the performance is horrendous, with the CPU getting fully maxed out and unable to keep up with setting the constraints for each cell as they are reused and placed with new text.
I was wondering if anyone knows of a better way to do this. Is there a way I can continue to use auto layout to size my cells without sacrificing performance? Or would the best solution be to create different sized cells with different identifiers, and just choose the best fit based on the UILabel text size.
I also read somewhere that UICollectionView has much better performance in displaying variable-sized content, would it be worthwhile/possible to try configuring a UICollectionView to display the messages, and somehow make it look like a UITableView?
Essentially I just need a suggestion on how to display messages of variable sizes (up to about 7 or 8 lines of text max) in a TableView-like manner without causing massive slowdowns as the user rapidly scrolls through the table.
Thank you
The best trick in the book for things like this is cacheing. Add to your model anything that's expensive to compute (not the views themselves, but the computational results, like view bounds sizes). Make your datasource methods all about looking up and assigning, not at all about computing.
The way I had implemented adding the constraints, the constraints were updated whenever [self updateViewConstraints] was called, regardless of whether or not the cell had already had its constraints calculated and applied. I resolved this by adding a BOOL property to my custom TableViewCell called didUpdateConstraints, and setting it to YES as soon as constraints are updated the first time. Then in my [self updateViewConstraints] method I only update the constraints if !self.didUpdateConstraints
Now that constraints are not being needlessly updated when all views have already been correctly constrained, the performance is significantly better, and I don't observe any slowdown upon scrolling through the table.
I am trying to repduce a similar sort of layout as in the screenshot below from the Digg app..
Notice that each list entry has a title in bold followed by the source, posted time and finally if there is enough space the start of the description line.
The question is what is the best way to achieve this in iOS? With some posts having longer titles than others I cannot simply say that the title label is 40px high and then place the Source label at 45 as the title will sometimes be longer and sometimes shorter.
Do I have to calculate the height of the label based on its contents before arranging the layout or is there some better way of doing this in iOS so that the views 'below' are automatically moved down?
Another alternative would be some sort of rich text label that I could add all the text to and have it automatically wrap round moving the later text down but I cannot find any sort of control in standard iOS / Xamarin (MonoTouch).
Any pointers would be greatly appreciated?
If you are using a storyboard the simplest way to achieve this result is to define different prototype cells. For example, you could define four different prototype cells, each one with a different layout like those shown in the example picture you provided. You can dequeue the appropriate cell based on the content you want to display so there is no need to adjust the layout in the code.
If you are doing everything in code, it's a lot more complicated since you have to build your own "layout engine" to adjust size and position of the views in your cell. You can have a look at XibFree or use MonoTouch.Dialog as suggested in the comments.