i need to present a running text stream in my apps, i got the running text from my server and i can see it using NSLog that the stream is running. The text is change and have a new line every second.
Since i'm newbie in iOS i already made a research and there are couples that i still confuse :
1.Between UITableView and UIScrollView, which one you recommended regarding the performance?
2.What is the right library to use?is it llike NSStream or i just present it to my UITable?
Will appreciate if you can have a snippet code or tutorial for this.
Thanks...
I don't have time to write the code, as it's not simple.
You will want to create a UITextView and append the string to the text view as you recieve new content.
UITextView is a subclass of UIScrollView, so you can use all UIScrollView operations on it, including scrolling down to the bottom as new content is added. This is the best way to have good performance, as UIScrollView and UITextView are both tightly integrated into the graphics hardware on the device.
If the text is really big (hundreds of megabytes) then you should also delete old text from the top of the text view as you add new text to the end.
Just use the code you have now, but instead of NSLog(), append it to the UITextView.
IMHO, UITableView would be ideal choice, since it's well optimized to reuse its cells. If you use scroll view, 3600 lines (that's 1 hour log) will probably end up with 3600 text views (or labels), while for table view, it would always be the number of rows visible on the screen.
For data model, I think you can just use a big array, which is continuously fetched with data from the server, possibly truncated when it gets too big (I mean deleting the very old lines).
Remember the rule of optimization: get it working first before optimizing it.
Related
I'm new to IOS development, I have a few questions.
1) What's the purpose of property rowheight on table view cell, I mean it does nothing even if I change its value, it always takes the value from its parent view i.e a tableview property rowheight? It visually changes in the IB but nothing happens when I run the app.
2) What's the purpose of Content View why is it even there? Let's say If I have to make some image equal to the height of the cell it restricts me. Or is there any way a content view can be changed to be equal to the cell height & width? I have to put constraints on the image in relation with the cell which is not the immediate parent of the image and I don't know if this is the correct way to do it.
3)How does Xcode Autocomplete works? like if I want to write a function tableview(_:tableview didselectrowwithindex:IndexPath) and I type tableview it shows a list, what to do next? I mean I can't type the whole fucntion with params or find the func in the huge list.
The height of the cell set at the IB is primarily used for simulation, the views described at IB are normally resized when actually used. E.g. you can set rows height to be 100 for the table view, 30 for some of the cells and keep the whole controller simulating a nice screen of iPhone 6. The same view will be used for all devices and will be scaled accordingly as well as the cells with the help of your delegate.
The content view is there for the reasons directly related to your additional requests. It holds all the content while there other views that accompany your content and are part of the cell like separators, accessory views, slide action views. Without a content view the responsibility of managing all the additional parts would most likely fall on you as a developer and while you might think that that is fine at the simple layouts, a simple enhancement to it would make a huge impact.
Fuzzy autocompletion at Xcode seems to be something Apple is working on now. If you can't wait and find it too difficult to navigate through the list, there are Xcode plugins available that provide fuzzy autocompletion.
Answering the question in the topic:
example: tableview(_:tableview didselectrowwithindex:IndexPath)
if you write tableview it will show all the symbols that start with tableview. For functions, it will show all the functions sorted by the second parameter name (didSelectRowWithIndex).
[EDIT]
it will autocomplete as far as the answer is unique and then show you a list full of options. I don't know any tricks to skip looking through the massive list. But after a while you'll know what you're looking for and it gets faster.
[\EDIT]
when you press tab, it
by the way: the delegate functions names start with the name of the object they're related to.
So UITableViewDelegate functions start with tableview.
as for your first two questions there are tons of answers for those questions on SO. This one seems closely related to yours.
Is the iOS 7 Apple Mail app is using a UITableview for the composing and viewing message screens? If so, why?
The composition screen appears to be using a UITableView with a UITextfield for the subject row and a UITextView for the message row. What is the benefit? There aren't any table rows similar enough to be reused (Max is 6 if you include cc and bcc), so I don't see a performance benefit. There is no Edit mode (i.e. move, delete rows) on these two screens. The resizing table rows necessary to accommodate long messages seems like an unnecessary headache.
I'm working on an app with a similar text input layout and number of fields. I initially planned to use a UIViewController with UITextField and UITextView placed on a UIScrollView. Examining the Mail app, I'm assuming there's a reason Apple would use a UITableView. Though I don't see what it is.
Insight appreciated.
Table views are REALLY good at a few things, and one of those things is creating forms. All you really need to do is add the fields to the cells and do a little cell customization, and the table view handles all the spacing, formatting, rotation, scrolling, etc.
I built an open source iOS form building library that is build on top of UITableView for just these reasons. (https://github.com/mamaral/MAFormViewController) In my case, if you need to move around or add a new field to the form, it's as simple as updating the data source with a new form-field cell, as opposed to creating a totally new textField, configuring it, determining the frame, moving everything above and below it around accordingly, etc. I would suspect these reasons are similar to why Apple would use table views for forms like the above.
The class chain is:
NSObject - everything subclasses this. you have to be really crazy to not subclass it
UIResponder - anything that responds to user input should be a subclass of this. the message view responds to user input
UIView - anything that draws to the screen should subclass this. the message view draws to the screen
UIScrollView - anything that scrolls should subclass this (note: that's not how it works on OS X! Only on iOS!). The message view scrolls, so it needs to subclass UIScrollView
UITableView - anything that has rows of data should subclass this. The message view has four rows, so it should subclass it.
Basically, it subclasses UITableView because it needs all of UITableView's functionality. So why not subclass it? You are saving yourself thousands of lines of code by doing so.
Duplicating all of UITableView's functionality is very difficult.
Chances are if you write an app without subclassing UITableView, it will be so sucky Apple might even reject it from the store, telling you to go back and make it work properly. Which would mean subclassing UITableView or else writing thousands of lines of code — for example Voice Over is a huge pain in the ass if you don't subclass UITableView.
If you don't want to restrict yourself to rows of data, consider using a Collection View.
I need to generate a text container that contains something like this:
This is some random text
where a few of the words are
coloured and clickable
The clickable words should have different actions bound to them and should be in a certain colour. The container will have a fixed width and I need to know the resulting height of the container given a certain text.
What I've tried: Tried making each word a separate UILabel, added actions where actions were needed, calculated line breaks myself. The problem with this approach was that it was too slow, especially UILabel sizeThatFits. I need to generate a lot of text for a scrolling UITableView and this approach killed the scrolling performance.
What I also tried: UIWebView. For a few different reasons, it's just not an option.
What I would prefer: A solution that does not require third party code. This is optional, though if they are open source. iOS 7-only solutions are acceptable.
Lastly, what needs to be fast is the generation of the text and the measuring of its height. Determining where to click is allowed to take some time.
See that https://github.com/mattt/TTTAttributedLabel
..but i not understood about height
If iOS only is an option, watch the WWDC 2013 session 210 "Introducing Text Kit". They show things that are at least very similar to what you are asking for.
I'd like to make a reader that behaves like Amazon's Kindle app. Specifically, I want to present a bunch of justified text in paragraphs, one column per page, and have it scroll between pages like the Kindle app does.
Let's assume I have the text in a simple format, like a text file per chapter, or even a string hard-coded in memory per chapter.
They're obviously using Core Text. Are they using a paged scroll view? Would that run in to memory problems for large books?
My initial thought is that they are using a UITextView to display a large amount of text, this kind of view allows you to add margin, padding, text and for iOS 6 you could use something like NSParagraphStyle to give styling to the text, the easy approach would be to create a really long text in different UITextViews within a UIScrollView and that would give you a nice result however if memory is a concern and the iOS version is not a problem I'd recommend using UICollectionViews, you can make each page a "cell" and then write some custom layout so when the user is scrolling the book you can actually just instanciate the page the user is using at a certain moment
The cool thing about NSCollectionView is that it behaves exactly like a UITableView so it's very memory efficient, something that is not on the screen is not displayed, and if it's going to be displayed then it's loaded.
hope this can give you some insight on the matter.
I ended up making something completely custom. It consists of 3 views, a left main and right view.
The view controller renders the text on the main view using Core Text, and calculates the size of the text frames (and therefore the number of pages) for each page in the current chapter.
If the user taps or drags right or left, the view controller will render one of the side views and let you drag it on. When you finish dragging or complete the tap action, it animates the pages into place, then swaps the main view with the one you dragged on.
The advantage to this method over using a UICollectionView is that it's very expensive to calculate the exact contents that should be displayed on a given page in a deterministic way, as a table/collection view would require. This way allows me to render the text of any chapter, and go back or forward lazily without laying out the whole book at once.
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)