What's the best layout for a scrollable iPhone "detail view" with variable content? - iphone

I'm building a navigation controller based iPhone application and am curious how to go about building the detail view for my application. The part that's complicating my endeavor is: What UI elements/hierarchy should I employ to create a variable-height yet scrollable detail view?
A great example of my goal is an arrangement like the mobile App Store detail view. The horizontal divisions between the heading, description, screenshot, etc leads me to believe it's a table view in disguise, but that's just a guess.
Currently, I'm using a UIScrollView for my detail view, but since I can never be sure of the exact length of my incoming content, my description view ends up with either unused space or truncated text. Is there some set of elements that would be best suited for displaying this variable-height content in "blocky" format (like the example) while still maintaining overall view scroll-ability?
Thanks in advance for your assistance!

If you want to be able to easily format complex content you can use a UIWebView. What I basically do is create an HTML template and add it as a resource. At run time I load the content of this HTML doc and do string replacement to add the content I want. Within the HTML I place placeholders like
<div><!-- ARTICLE_TITLE --></div>

I don't think the App Store detail view is a UITableView. In fact, I'm pretty sure it's a subclass of UIScrollView.
To determine the size of your content, you can use NSString's sizeWithFont method.

A little late, but still relevant: The App Store broke a few weeks ago, and the "Featured" tab of the App Store was very obviously HTML without CSS applied. So, it's actually a UIWebView, or web content displayed in some fashion.
The touch-down behaviors of the iTunes app, while appearing quite similar, behave differently, in a more native fashion. I'm not convinced this app is implemented in the same way.

Related

Flip from one ViewController to another iBooks Style

I'm trying to load in content from a database and allow the user to flip through it like pages, then at the end of the content, give them options to go to another section of content (probably with buttons). The content is currently just formatted with html, but how do I implement the buttons to navigate? I'm a little new to Xcode so maybe I'm not even looking in the right direction.
refer a this opensource: https://github.com/devindoty/iBooks-Flip-Animation
this is very little code and perfectly works.

Editable UITableViewCell having a left-aligned label

I am very new to iphone application development and am struggling to create a table view page where each row contains a left-aligned label with an editable text next to it - just like how it works in the email account details page in the settings application on my iphone.
I have been googling the subject for hours and it is now somehow clear to me that I need to add UITextFields to UITableViewCells, but it is still not at all clear to me how I make these text fields take up the right amount of space:
How do I make the text fields align above each other?
How do I make the text fields expand as far as possible to the right?
How do I prevent the text fields from hiding part of the left-aligned label?
Read the Apple Docs on Tableviews there are a number of predefined table cells. Also look at the Tableview programming Guide. Pick the one that has the font characteristics that you want and Apple will take care of it for you. Also, in the Settings app, the settings are a Grouped style.
For the look you are describing I think it is called UITableViewCellStyleSubtitle.
You need custom UITableViewCells and there are a number of ways of making them. For your purposes, any one of the techniques detailed in the Apple documentation will probably suffice.
An alternative to those approaches is in GSUtils (full disclosure: open-source library written by me), where you can use the same approach to designing your table view cells as you would design a UIView.

Rendering a Long Document on iPad

I'm implementing a document viewer with highlighting/annotation capabilities for a custom document format on iPad. The documents are kind of long (100 to 200 pages, if printed on paper) and I've had a hard time finding the right approach. Here are the requirments:
1) Basic rich-text styling: control of left/right margins. Control of font name, size, foreground/background color, and line spacing. Bold, italics, underline, etc.
2) Selection and highlighting of arbitrary text regions (not limited to paragraph boundaries, like in Safari/UIWebView).
3) Customization of the Cut/Copy/Paste popup (UIMenuController) This is one of the essential requirements of the app.
My first implementation was based on UIWebView. I just rendered the document as HTML with CSS for text styling. But I couldn't get the kind of text selection behavior I wanted (across paragraph boundaries) and the UIMenuController can't be customized from within UIWebView.
So I started working on a javascript approach, faking the device text-selection behavior using JQuery to trap touch events and dynamically modifying the DOM to change the background color of selected regions of text. I built a fake UIMenuController control as a hidden DIV, positioning it and unhiding it whenever there was an active selection region.
Not too shabby.
The main problem is that it's SLOOOOOOOW. Scrolling through the document is nice and quick, but dynamically changing the DOM is not very snappy. Plus, I couldn't figure out how to recreate the magnifier loupe, so my fake text-selection GUI doesn't look quite the same as the native implementation. Also, I haven't yet implemented the communication bridge between the javascript layer and the objective-c layer (where the rest of the app lives), but it was shaping up to be a huge hassle.
So I've been looking at CoreText, but there are precious few examples on the web. I spent a little time with this simple little demo:
http://github.com/jonasschnelli/I7CoreTextExample/
It shows how to use CoreText to draw an NSAttributedText string into a UIView. But it has its own problems: It doesn't implement text-selection behavior, and it doesn't present a UIMenuController, so I don't have any idea how to make that happen. And, more importantly, it tries to draw the entire document all at once, with significant performance degradations for long documents. My documents can have thousands of paragraphs, and less than 1% of the document is ever on screen at a time.
On the plus side, these documents already contain precise formatting information. I know the exact page-position of every line of text, so I don't need a layout engine.
Does anyone know how to implement this sort of view using CoreText? I understand that a full-fledged implementation is overkill for a question like this, but I'm looking for a good CoreText example with a few basic requirements:
1) Precise layout & formatting control (using the formatting metrics and text styles I've already calculated).
2) Arbitrary selection of text.
3) Customization of the UIMenuController.
4) Efficient recycling of resources for off-screen objects.
I'd be happy to implement my own recycling when text elements scroll off-screen, but wouldn't that require re-implementing UIScrollView?
I'm brand-new to iPhone development, and still getting used to Objective-C, but I've been working in other languages (Java, C#, flex/actionscript, etc) for more than ten years, so I feel confident in my ability to get the work done, if only I had a better feel for the iPhone SDK and the common coding patterns for stuff like this. Is it just me, or does the SDK documentation really suck?
Anyhow, thanks for your help!
Does your document have any semantic components other than each paragraph? If you already have some concept of sections or pages, I would recommend you render each one of those as an independent tablecell. It's pretty simple to create a tablecell that makes you forget you're actually looking at a UITableView. All you would need to do is override drawRect: and setSelected: and setHighlighted: and tah dah! No More cell dividers unless you want them. Furthermore you could do some nifty things by using a tableview as your base. If you defined sections in the UITableView then you could have a nifty header that scrolls along as you're paging through your document. Another thing you could do is add a "jump to section" bar / a bookmarks menu, and that way you don't have to provide selection across the boundaries of sections.
Massive copy paste blocks would be pretty painful on the system as well. Further, if you went through the trouble to provide this content you might not want to make it too easy for someone to copy it all at once... (Can't follow this line of thought more without more specifics on your project).
If you really do want to provide the copy paste options you could add buttons to each logical page or section that immediately selects and copies the whole section for the user's convenience. (Maybe with citation associated?)
I recommend you lookup the UITableViewCell UITableViewDelegate and UITableViewDataSource in the SDK docs as those pages will significantly help if you choose to use this suggestion.
Just two random observations:
Can you afford to create a paging interface? (As opposed to “endless scrolling”.) It looks like a paging interface would be a lot easier on system resources.
The UIActionBar is actually the UIMenuController class. The interface is a bit weird, as the menu is a singleton (wtf?), but I’m sure you’ll have no trouble figuring it out.
Hope that helps.
Here's a potential solution, but I don't know if it's crazy. Since I'm still so new to iPhone development, this might be a big no-no.
Anyhow, I had the idea to render each paragraph of the document (whose dimensions I've already precisely calculated) as a cell in a UITableView. Since UITableView already has mechanisms for cell recycling, I wouldn't have to implement that from scratch, and the document could be arbitrarily long without causing resource consumption problems.
Of course, I'd want to get rid of the line separators between cells, since I want the UI to look like a document instead of a table.
Or maybe I could render each page of the document (like a typical PDF, this is a paged-document format) as a table cell, and override the cell-separator graphic to look like a page boundary...
But would it be possible to get rid of the default touch behavior within the table, and instead implement text-selection on the table cell contents? Would it be completely impossible to implement text selection that crosses paragraph boundaries (between multiple table cells)?
The UIWebView is a good choise, but we need another application to pre render the pages percisely using each font and each style sheet and store the rendring information into a database table:
chapter_id int primary key,
startlocation int,
end location int,
fontsize int (or stylesheetname string)
Using JavaScript we can calculate how many words fit in a div with out scrolling.
UIWebView is good as it provide rich content and it has selection and highlighting behavior.
Hope this helps.

UITableViewCell with selectable/copyable text that also detects URLs on the iPhone

I have a problem. Part of my app requires text to be shown in a table. The text needs to be selectable/copyable (but not editable) and any URLs within the text need to be highlighted and and when tapped allow me to take that URL and open my embedded browser.
I have seen a couple of solutions that solve one of either of these problems, but not both.
Solution 1: Icon Factory's IFTweetLabel
The first solution I tried was to use the IFTweetLabel class made possible by Icon Factory and used in Twitterrific.
While this solution allows for links (or anything you can find with a regex) to be detected to be handled on a case by case basis, it doesn't allow for selecting and copying.
There is also an issue where if a URL is long enough to be wrapped, the button that the class overlays above the URL to make it interactive cannot wrap and draws off screen, looking very odd.
Solution 2: Use IFTweetLabel and handle copy manually
The second thing I tried was to keep IFTweetLabel in place to handle the links, but to implement the copying using a long-tap gesture, like how the SMS app handles it. This was just about working, but it doesn't allow for arbitrary selection of text, the whole text is copied, or none is copied at all... Pretty black and white.
Solution 3: UITextView
My third attempt was to add a UITextView as a subview of the table cell.
The only thing that this doesn't solve is the fact that detected URLs cannot be handled by me. The text view uses UIApplication's openURL: method which quits my app and launched Safari.
Also, as the table view can get quite large, the number of UITextViews added as subviews cause a noticeable performance drag on scrolling throughout the table, especially on iPhone 3G era devices (because of the creation, layout, compositing whenever a cell is scrolled on screen, etc).
So my question to all you knowledgeable folk out there is: What can I do?
Would a UIWebView be the best option? Aside from a performance drag, I think a webview would solve all the above issues, and if I remember correctly, back in the 2.0 days, the Apple documentation actually recommended web views where text formatting / hyperlinks were required.
Can anyone think of a way to achieve this without a performance drag?
Many thanks in advance to everyone who can help.
As soon as I hit the submit button, a new idea hit me.
I was so preoccupied with having URLs inline with text and interactive that I didn't consider that maybe it's not the best solution.
I'm certain that to achieve that kind of behaviour, a UIWebView is the best choice, regardless of the performance issues.
However, maybe a better user experience / interaction is to not highlight the URLs inline, but to gather them into an array behind the scenes, and present a disclosure button as the cell's accessory view?
Then for selection and copying text, I could just use the UITextView with data detectors turned off and not worry about the links being sent off to safari and closing my app.
When the disclosure button is tapped, the user could be whisked off to the URL found in the text, or if more than one URL is found, present the user with a picker view to choose which to go to.
Any thoughts/criticisms of this idea are welcome.
You can prevent a textfield from being edited by overriding the UITextField Delegate methods such that they do not apply any edits. That leaves the field selectable and copyable but prevents alteration.
A better question to ask is: do you actually have to display the actual URL itself? Can you get away with just a page/location name, just the server.host.domain prefix or some other condensed representation of the url? I don't think anyone whats to try to read a long url on a mobile's restricted screen.
If you do need to display the entire url then I think that a detail view is the way to go.

Best approach for adding non-web links to UITextView

I am creating a dictionary-style app that presents a tableview full of words, and when a word is selected, a UITextView is displayed that shows the definition of the word. What I would like to do is add a line that says "See also: synonym1, synonym2" where synonym1 and synonym2 are links that will take the user to the definition for the synonym that is touched.
What is the best way to add these dynamic links? Buttons? Somehow add a small UIWebView a UItable on the fly?
Thanks!
I would replace your UITextView with a UIWebView and use that contain your description text and your links. It's fairly trivial to generate HTML on the fly for something like that.
You could register a custom URL scheme for your app, or you could intercept links as they're clicked.
If your links are always grouped together there's no reason why you couldn't use a bunch of UIButtons inside a custom view, but then you'd have to handle layout and wrapping on your own. It seems a lot easier to do it in HTML.