I add a PickerView to one of my views in an app, but its size is too small(in height). I find that I cannot drag to make it "longer". How to change its size then?
The only way is by adjusting the pickerView.frame.size.height, but you'll get some pretty bad visual artifacts.
I would think long and hard about attempting to circumvent the established design of this control. If you have so many items or your items are too big for this view, a UITableView is probably what you want to go with. It's far more customizable and can handle items/cells of all different shapes and sizes.
Related
I am currently trying to get the hang of Auto-layout in Xcode, and with it, i have found some problems.
Now, i don't have a 100% grasp on how auto-layout works exactly, so as i learn on it might become easy, but i think it is very hard to be honest. I am usually making games, and of thus, i programmatically add a lot of views to the screen. Now, auto-layout seems to mess everything up when i do this, so i constantly have to make sure that every single auto-layout feature is just right, and there are a bunch!
So, if you do not want to support other orientations, is auto-layout really needed? i mean, if i am making a game for the iPad and using landscape mode only, is there any reason for me to use auto-layout?
Thanks on advance
A couple of thoughts:
Auto layout is not mandatory.
But auto layout provides a mechanism for dealing with situations when views change sizes and/or locations:
changing orientation, as you pointed out;
supporting different screen sizes (e.g. iPhone 3.5" screen vs 4.0" screen);
controls whose size changes based upon content (e.g. a UILabel whose width expands to fit the text or whose lineCount is set to zero, meaning that its vertical will grow based the number of lines needed to fit all the text); with auto layout you can establish dependencies between controls so that, for example, as one control changes its own size/location, others can move/resize accordingly (e.g. to stay aligned with or make room for the other control); and
automatically update contentSize for UIScrollView objects.
Auto layout requires a little time to gain proficiency, but for dynamic, complex user interfaces, it can save you from having to write code to manually change layouts of views programmatically. But if you don't find yourself doing this sort of code, then you don't necessarily have to use auto layout.
I should acknowledge that there are some tasks that are trivial in a non-autolayout environment (e.g. animation of moving views), doing the same task in auto layout can be frustratingly complicated. But if you have complex interdependencies between views (either between the superview and its subviews or between sibling views), auto layout can be useful.
Autolayout simply provides rules for the views how they appear in all orientation.It is upto the user to define how to use it or you may follow the struct and spring model .
The major difference between the two is that there no dimensions involeve in the struct and springs while autolayout says the dimensions and values in whch views should be rearranged
An excellent beginner tutorial fo autolayout
My app is behaving sluggishly. If i pop up a UIActionSheet, for example, instead of rolling in smoothly, it stutters in over about 5 frames. I know ideally you should have as little amount of views on screen as possible, but that's what I've got anyway.
Any suggestions for speeding it up?
EDIT:
On my view i have:
Custom navigation bar in place of the regular one. It's a UIImageView, using an image file. It has a quartzcore shadow. It contains 3 buttons. 2 of these buttons have 2 UIImages each, for normal and highlighted, generated from code when the view is shown. The other button uses an image file for normal and for highlighted.
An image file for a background lies under that. On top of the background is a UITableView. By default, it doesn't have any cells (the user adds them). We'll ignore the cell, since it's slugging regardless of their being there or not.
The header of the tableview contains some labels, and an editable uitextview. The size of the header changes as more lines are added to the textview. It also has a background image, which is transparent to allow you to see the view's background image behind it. It's loaded from a file, and a texture image on top of that is also loaded from a file.
The footer is simply a background image loaded from a file with the same texture on top.
Andrew, I'm afraid you haven't been quite specific enough to isolate the exact problem. However there are a couple of things I have picked out. Firstly, check your table view is set to be opaque. Also try to design your app so your table cells can be opaque. I'm assuming your design will allow this. You need to really know how to optimise view rendering performance if you want your table and it's cells to appear translucent over other content and it may be you would need to develop your own custom specialised alternative to UITableView if that is something you really need to know (can be done but quite advanced stuff).
Also you mention using Quartz shadow. You should be able to use UIKit for drawing shadows around images, unless you have some specialist requirement. Are you sure you need to use Quartz for what you want to do? Apologies if you already know this, but if you are fairly new to iOS development and have been looking up how to do shadows, you may have found the Quartz API's for doing that and assumed that is the solution, when (depending on what you need) you will probably be better off staying with UIKit. As a general rule of thumb, only use Quartz if you are sure you can't do what you want to do with just the UIKit API's.
Another thing to check. If you are using Quartz, then you are probably getting getting the graphics context for the UIImage view and drawing on the views context in drawRect: depending on how your view hierarchy is configured, and if you have your navigation bar view set to be transparent over the top of the UITableView, then your custom drawRect implementation may be getting called unnecessarily with every animation frame and this would be a big drain on performance.
Given the level of information you have given I'm having to guess a bit and can't give a precise answer. However for a definitive understanding of how to optimise UIView performance I recommend checking out this video (though you will need an Apple Developer account to be able to access it):
https://developer.apple.com/videos/wwdc/2011/
Session 121 – Understanding UIKit Rendering
Hope this helps. Paul.
I have an infinite scrollview in which I add images as the user scrolls. Those images have varying heights and I've been trying to come up with the best way of finding a clear space inside the current bounds of the view that would allow me to add the image view.
Is there anything built-in that would make my search more efficient?
The problem is I want the images to be sort of glued to one another with no blank space between them. Making the search through 320x480 pixels tends to be quite a CPU hog. Does anyone know an efficient method to do it?
Thanks!
It seems that you're scrolling this thing vertically (you mentioned varying image heights).
There's nothing built in to UIScrollView that will do this for you. You'll have to track your UIImageView subviews manually. You could simply maintain the max y coordinate occupied by you images as you add them.
You might consider using UITableView instead, and implementing a very customized tableView:heightForRowAtIndexPath: in your delegate. You would probably need to do something special with the actual cells as well, but it would seem to make your job a little easier.
Also, for what it's worth, you might find a way to avoid making your solution infinite. Be careful about your memory footprint! iOS will shut your app off if things get out of hand.
UPDATE
Ok, now I understand what you're going for. I had imagined that you were presenting photographs or something rectangular like that. If I were trying to cover a scroll view with UILeafs (wah wah) I would take a statistical approach. I would 'paint' leaves randomly along horizontal/vertical strips as the user scrolls. Perhaps that's what you're doing already? Whatever you're doing I think it looks good.
Now I guess that the reason you're asking is to prevent the little random white spots that show through - is that right? If I may suggest a different solution: try to color the background of your scroll view to something earthy that looks good if it shows through here and there.
Also, it occurred to me that you could use a larger template image -- something that already has a nice distribution of leaves -- with transparency all along the outside outline of the leaves but nowhere else. Then you could tile these, but with overlap, so that the alpha just shows through to the leaves below. You could have a number of these images so that it doesn't look obvious. This would take away all of the uncertainty and make your retiling very efficient.
Also, consider learning about CoreAnimation (CALayer in particular) and CoreGraphics/Quartz 2D ). Proper use of these libraries will probably yield great improvements in rendering speed.
UPDATE 2:
If your images are all 150px wide, then split your scrollview into columns and add/remove based on those (as discussed in chat).
Good luck!
I have a bit gantt chart that i want to be visible on an iphone.
It is 7200 x 1800px large, and consists of ~600 bars, each of which is a UILabel.
It is to look like this:
Now i've gotten it to work. And at ~100 bars, i can make it run quite smoothly by simply adding them all to the scroll view. However, with the full 600 (or more eventually) it simply crashes when i instantiate all those uilabels and add them all to the scroll view as subviews.
So what i've done is made it create only the uilabels for the currently visible rows, and as the user scrolls up and down it removes the invisible uilabels and adds the newly visible ones.
However, this jerks quite noticeably as you scroll vertically as it crosses each row boundary, and has to render another row and remove the old row.
Does anyone have any suggestions to solve this? Any ideas what is the slow part? Instantiating the uilabels, or adding them as subviews, or anything?
All help will be greatly appreciated.
Apple has some really good demo code that shows how to do this. Check out TiledScrollView.m especially the layoutSubviews method.
Other things you might consider:
If you labels are quite long horizontally you may need to break them into smaller chunks. Quite long in this context is wider than the screen.
Make sure your UILabels are opaque. Scrolling things that require compositing adds extra overhead which may account for some of your issues.
Looking at your screen shot the row and column headers are not opaque and are using alphas. Whereas this is a nice effect it may be worth temporarily making them opaque too just to see if this is contributing to your problems. I don't think this is contributing too much to your problems; the area being composited is quite small.
Just a thought, but could the issue be that even though you are caching and reusing the labels, is the scroll view still retaining them, so even though you may only have a few labels, each is being retained hundreds of times. If this is so then I would think that the scroll view is still effectively trying to manage those hundreds of rows.
So as #Nathon S asked - are you moving them? i.e. building a finite set of labels and just moving them around on the scroll view to match the viewing area. If you are hiding and re-adding to the scroll view then I would suspect a massive set of retains being the slow down. I would think that with a moving label design, you would not need to do any hides and adds after the the initial display. Which should make it very fast and lightweight.
I'm trying to implement a view that shows a grid of information without using a UITableView, however, since I'm displaying about 36 different statistics, with its label I will have to initialize and use 72 UILabels. Does having so many UILabels mean that my iPhone app's performance will be significantly negatively affected? Is there a way to reuse some of the UILabels to decrease the number of UILabels that must be loaded at one time, or should I just resort to drawing everything on a surface instead?
First of all you should test the interface your thinking of and see if it takes a performance hit. Having a lot of labels all loaded at once will increase your memory footprint but depending on what else is going on in the app, it might not matter.
Secondly, you can't easily reuse the labels but it is possible. However, you would have to constantly monitor the displayed area of the scrollview and move the labels frames around as the view scrolled. I doubt you could do that efficiently. It would take a lot of coding in any case.
Thirdly, any grid like layout can be easily displayed in a table without making it look like a table. For example, the photopicker layout is a table but it looks like a bunch of icons on a white background. Another app I saw used a table to display paragraphs of text but it looked like an ordinary scrolling textview. Every row in a table can be customized to display exactly what you want. In principle, you could use a different cell for every row and they could all be unique in their height and contents.
The advantage of the table is the the table manages what is and is not on screen for you. It does reuse cells and their contents which makes them more efficient. The table also makes it easier to manage a lot of data.