I'm using a UIPickerView in a somewhat unorthodox way to allow users to select a series of images (in this case, they're words on a background, but they can just easily be pictures):
Under iOS6 this worked great, but with iOS7 as you can see, the edges of the images fade to white, which makes the control unusuable for this purpose.
My question are --
a) Would there be a way of "fixing" this and still using the UIPickerView control? If so, what kind of approach might one take?
b) If I can't modify the views to eliminate the problem, would a practical alternative to be to use three UIScrollViews to replicate this functionality?
c) I have at times modified the views presented in a UIPickerView, and I'm considering trying to do that here, i.e., to just plug in my own replacement views. But I'm unclear on whether that is practical... I'm questioning how the blur effect is added to these views at the top and bottom and how I might go about eliminating them.
That's a lot for one post; I'm just trying to decide what the best approach might be to deal with this issue.
TIA for any suggestions or guidance...
I ended up making some adjustments to the implementation that improved the appearance somewhat. We slightly increased the overall size of the picker by scaling it 1.25 (when in portrait view) or 1.40 (when in landscape view). At the same time, I slightly reduced the size of the images in the picker. The end result was that overall the frame was bigger, but the images were about the same size as before. But the regions where the appearance is blurred are safely out of view unless one really looks hard for them. We have judged this will work for now.
Ultimately, the UIPickerView has, in our opinion, taken a huge step backward with ios7. We are anticipating the need to write something of our own to accommodate our needs in the long run but these changes have allowed us to get by for now.
Related
Today I heard about new approach of design views in storyboard
Lets consider one page contain image , label and button now out storyboard as follow
1] our one UIViewController divides in three part i.e 3 UIViews for 3 components like one UIView for image
2] for keep image responsive take another UIView and keep imageView inside that and then set constraints and keep wight and height of imageView aspect ratio.
3] I given different colour for different UIViews for understanding
final hierarchy is as below
So as per screenshot you can see view are more responsive and changes made in one UIView is not reflect is another one and our hierarchy of view are maintained .
Finally come to the questions
1] is this approach correct?
2] is there any impact of this much UIView views on application in terms of memory and performance?
Answer on first question:
The approach how to handling lot of views? No it is not correct. If you had lot of views in scrollView use UITableView or UICollectionView, because of better handling, reusing and layouting - features provided by UIKit for free. If you have lot of views on one screen without scrolling - try to use UIStackView - it will provide you lot of automatic layouting and very easy editing and updating layouts instead of using autolayout / layout masks. UIStackView can be considered as AutoLayout generator machine.
Answer on second question:
No. Using large storyboards has no much bigger impact on memory and performance, than generating it via code.
There is two main problems with storyboards:
1) Large storyboard has performance impact on XCode. Especially with older Macs.
2) If two or more people working in one storyboard simultaneously, you need to be aware, not to edit same ViewController together, or creating new, otherwise you will have repository conflicts (same as 2 persons edit same piece of code at same time), but you have to resolve it in xml, what is readable, but it takes some time to understand.
I tried this method a lot and I realise this approach solve lot of problems of setting constraints. This approach is similar as Bootstrsp . We are going to divide hole screen by UIViews and Finally put our main design views in it. Till now I don't know what is bad impact of this approach in application in terms of memory and speed. That I will explain in future.
Thanks a lot.
EDIT:
Imagine that I'm in the business of reimplementing CoreText.
I'd get an NSString here which is an ordered list of code-points, and a set of glyphs there (an NSFont/CTFont) that basically is a list of CGPathRef.
Something in-between is in charge of the layout.
And some kind of environment must provide a CGGraphicContext to render into.
The kind of objects I have to display are CGPath. I am worried of creating one UIView for each CGPath! For a block of text, you wouldn't create an UIView for each character-glyph, would you?
I have a potentially large set of (tiny) objects to draw at once. In the 1000's. Many will be offscreen until scrolled into view.
One one hand it looks like my best bet would be to create one UIView for each one. The reasons are that:
with proper tiling I can make sure that the views that are offscreen
are not even in memory most of the time and brought up to life when
required
more importantly, when zooming I want to set each such view's layer contentScale to the zoomFactor such that I still get the full
precision and not the blurry stair-case
On the other hand I have no idea how the (otherwise perfectly generic) parent view will behave with 1000's of children.
So I am tempted to rethink my code such that the "children" just become an area of the single view.
But then I start thinking of setting that view's layer contentScale and I'm worried about exhausting memory just while zooming: I do not know if the layer machinery is "clever" enough not to create a huge backing bitmap when most of its contents would be invisible anyway
What to do, oh what to do?
Anyone has any experience they want to share?
I recently saw a presentation on a game involving hundreds of sprites implemented as UIViews, mostly image views. Performance was excellent on both an older and recent generation iPad. His code is available at https://github.com/bentford/ButtonWars/ , so you may want to test it to see if the performance meets your needs.
There is often an assumption that views are heavyweight, but experience doesn't bear that out.
If most of the objects will not be on the screen at any time, it's probably better not to create views for all of those off-screen objects. You need to intelligently add views for just those objects that are visible, and remove them from the view hierarchy when they go off-screen. You might be able to use UICollectionView to make this easy - it is very well designed, efficient, flexible, and easy to use and customize - but I don't know if it works with zooming.
If you decide to draw everything in one view, with deep zooming, you should look at CATiledLayer. It is designed for zooming in very deeply. Apple's MKMapView uses it under the covers to support scaling its viewport from Earth-sized down to a (relatively) few square meters.
If you cant use UICollectionView due to iOS version boundations, and you are intrested in re using views in UIScrollView, than have a look at this class. It is used the same way UITableview is used. Just pass in number of views and it will reuse the views.You can go through readme. Its very straightforward.
I'm new to iOS development pondering how best to approach a fairly simple design problem. I want to display a set of items, each one of which has the structure as sketched. In a given set, not more than 10's of items.
Each item includes a thumbnail image, a heading, a blurb, and a set of buttons. There are two complications:
The amount of text and number of buttons is variable.
The text requires some internal formatting (italics and bold).
I've considered these approaches:
Use a table view, with custom, resizable UITableViewCell, probably using something like OHAttributedLabel for the text. For the variable number of buttons, either lay these out programmatically or possibly use the new collection view (for older iOS, have to use 3rd party grid view).
Use a table view with custom cell based on UIWebView.
Do the whole set as one UIWebView.
Use a table view with sections; each item having its own section and parsing out the buttons and text to rows.
Would love to get suggestions about how a more experienced iOS dev would approach this.
EDIT: I am now considering that the best way may be:
5) Use UICollectionView for the whole thing.
UPDATE: In the end, I laid the whole thing out in code as a custom table cell (ie., #1). This was a good choice, not only for the reasons given in the answer, but because as someone new to iOS development, it's something I needed to get under my belt. Didn't even use collection view for the buttons, because I was worried about performance and also the hassle of supporting iOS5.
I do think that using collection view for the whole design (#5) would have been an elegant solution, and I actually started down that path. However, some complications not shown in the simplified pic above made that unwieldy.
2nd UPDATE: #1 turned out to be a dead end. My final solution used a UIWebView (#3) - see answer.
I have found some resources that might be useful to some people who is doing complex tableviewcell and want fast scrolling. I am still developing it, but I want to share this first to you guys.
Facebook iOS release note: they mentioned techniques: core text, pre/asynchronous calculation of table height, do a lot of things on background thread, save layout attribute in core data. http://www.facebook.com/notes/facebook-engineering/under-the-hood-rebuilding-facebook-for-ios/10151036091753920
Fast scrolling sample: https://github.com/adamalex/fast-scrolling
Apple's sample project TableViewSuite. The 4th example.
https://developer.apple.com/library/ios/#samplecode/TableViewSuite/Introduction/Intro.html
Very close to solution..YES
I know this is an old thread, but I found it very interesting, as I am just now getting around enough as an iPhone developer to reach these types of performance concerns. I found a very interesting article on Facebook's site by Facebook Engineering describing how they implemented UITableView and overcame the dynamic sizing issues, also with rapid content management. It seems they precalculated using deeper objects and kept everything asynchronous and pre-cached where possible. I'm going to provide a link to the article, but I'm going to copy the section that tackles exactly this problem. I hope you find it useful. Here's the link, https://www.facebook.com/notes/facebook-engineering/under-the-hood-rebuilding-facebook-for-ios/10151036091753920, and the most relevant excerpt:
(Re-)Building for Speed
One of the biggest advantages we've gained from building on native iOS has been the ability to make the app fast. Now, when you scroll through your news feed on the new Facebook for iOS, you'll notice that it feels much faster than before. One way we have achieved this is by re-balancing where we perform certain tasks. For example, in iOS, the main thread drives the UI and handles touch events, so the more work we do on the main thread, the slower the app feels. Instead, we take care to perform computationally expensive tasks in the background. This means all our networking activity, JSON parsing, NSManagedObject creation, and saving to disk never touches the main thread.
To give another example, we use Core Text to lay out many of our strings, but layout calculations can quickly become a bottleneck. With our new iOS app, when we download new content, we asynchronously calculate the sizes for all these strings, cache our CTFramesetters (which can be expensive to create), and then use all these calculations later when we present the story into our UITableView.
Finally, when you start Facebook for iOS, you want to see your news feed, not a loading spinner. To provide the best experience possible, we now show previously-cached content immediately. But this introduces a new problem: If you have a lot of stories in your news feed, UITableView throws a small spanner in the works by calling the delegate method -tableView:heightForRowAtIndexPath: for each story in your news feed in order to work out how tall to make its scrollbar. This would result in the app loading all the story data from disk and calculating the entire story layout solely to return the height of the story, meaning startup would get progressively slower as you accumulate more stories.
The solution to this particular problem has two main parts. Firstly, when we do our initial asynchronous layout calculations, we also store the height of the story in Core Data. In doing so, we completely avoid layout calculation in -tableView:heightForRowAtIndexPath:. Secondly, we've split up our "story" model object. We only fetch the story heights (and a few other things) from disk on startup. Later, we fetch the rest of the story data, and any more layout calculations we have to do are all performed asynchronously.
All this and more leads to high frame rates while scrolling and an app that remains responsive.
I originally accepted (and implemented) #Daij-Djan's answer, but now I believe the best approach is #3 (UIWebView). It comes down to performance.
UITableView strains to perform well with custom cells with subviews, especially in the context of cells with varying heights. The rows of buttons make the scrolling choppy. As suggested by Apple in Cells and Table View Performance , I made sure that subviews were all opaque, however there is no way to follow the suggestion of "Avoid relayout of content."
Add onto that dynamic cell heights and attributed strings and these tables scroll pretty poorly. I suppose the next optimization would be to override drawRect, but at that point I decided to try UIWebView.
UIWebView is not without its performance issues either! Its scrolling performance degrades pretty fast as the content grows, however, I can manage that by hiding content and letting user "open" it as desired.
no 1 is maybe the most work directly followed by #2 BUT
as ACB said, it's also the most flexible and IMO will surely provide the best look'n'feel
no 3 works but will not feel as smooth / alway be tad 'html-ish'
no 4 sounds like highway to hell (later on. it will be a PITA to modify/maintain)
In my two recent questions here and here I laid out my problem a bit, but I want to ask a more general question here. First my goal: I am trying to animate views side to side with a fixed background image.
I am new to iOS, and so I don't know all the tools that are available to me, but each time I started hacking this together I kept thinking that there must be a built-in way to do this. I didn't want to reinvent the wheel, so what is the common way to implement this?
The best approach I think is making a UIView based in two main views:
The background, that always will stay
And on top of it, another UIView with your animated view
In case you want to animate it, its quite easy, just check this:
iPhone UIView Animation Best Practice
I'm looking to build a document "selector" screen, similar to Pages and Numbers on the iPad/iPhone:
I come from a WPF background and have some iOS experience. That being said, I'm looking for a good approach to building something like the tile-based interface Apple uses for opening documents in Pages.
I'm not concerned with the Folder animation.
What is the best way to approach building just the tile interface? I'd imagine I'd build some sort of view that sits within a UIScrollView - but it's the nature of that subview that I'm a little confused about. Does iOS have any wrap-panel or grid-like controls I could load a set of tiles (i.e., documents) into?
What do you guys think?
I don't know of any third-party classes to handle this for you, but there might be some out there.
The basic structure will be a UIScrollView containing a set of views, each representing one cell on the grid. You set the scroll view's contentSize based on the total number of tiles. Then you create tile views on demand, and place them inside the scroll view.
The scroll view's delegate object will be responsible for monitoring the scroll position, putting down tile views as they become visible, and (optionally) removing tile views that move out of view. This is basically how UITableView works: there are only about six or so instances of UITableViewCell at any given time, they are recycled as you scroll up and down the view. (Imagine a train where somebody at the back end is pulling out the rails and passing them forward to somebody in the front, putting them down in front of the train. As far as the train knows, the rails go on for miles.)
If you wind up having to place all the views yourself, take some time to learn the CGRect family of methods, including CGRectDivide. They will be useful in laying out the views and also in computing what's visible and what's not.
There are a few third party classes/libraries you can get to produce this functionality, AQGridView comes to mind. But there are no default easy classes for this.
If I was to develop this type of implementation, I would subclass UITableViewController. Expand it to have columns. Then subclass a UITableViewCell to display the image. That way all the container code and everything would already be there, and all you have to do is customize it to f it your needs.