I find some iphone book apps have such feature:
One screen one page of text without scrolling. The text can just fit into the whole screen with linebreaks and indentations.
I'm curious of how to implement this. How could I decide the length of text that just fit into the screen. And also, given the whole text, I can calculate out the number of pages.
If this is not possible to be done on iPhone(runtime?), then is it possible to process the text before storing it in app? I mean I calculate how many pages I need(how to split the raw text), probably how many lines per page.
I think this is what you are looking for
iPhone SDK: How do you measure the width and height of a string using Quartz?
The accepted answer gives methods you can call on NSString to calculate sizes
What I did for TouchTomes' books was have two iPhone apps. One was the reader that showed up on the App Store. The other was a renderer that calculated what could fit on each page, that only needed to be run in the simulator to create a book DB that the reader could use.
It would throw up a bunch of text, say 100 words, and see if that overflowed or underflowed. If it underflowed, more text was added (say 20 words) and it would binary search until it found exactly how much text would fit. Then it stored in a SQLite DB a row saying "page 12 shows words 100-228" for example. The app would go through this for each font. Another table held all the words in individual rows (!). An optimization step would chop that table down, combining words that always appeared on the same page no matter what font.
I used a Webkit display so the book could include HTML formatting. Now that really complicated the page breakup (e.g. had to keep italics going from page to page) but it let me include some fancier formatting in the text.
Then the reader app had very little to do to display pages; from the page id look up what range of words go on that page, then throw that text up into a webkit view. The user could jump between pages all over the book very quickly, all the hard CPU work had already been done by the rendering app.
Related
I would like to make a hybrid app using Flutter. One particular kind of component I'm looking at sounds something like this:
A Chinese character like 家 (which means home) is shown
When an user clicks on the character, it can display its pronunciation (jia)
The user also has the option to click to play the pronunciation
The user can also choose to open a window where an animation of how the character is being written is played.
So for a sentence like: 蓝天是白云的家(literally translated as: The blue sky is the home of the white clouds), each of these 7 characters can be individually clicked and users can choose to display / play pronunciation / show how they are written.
Normal static text won't be rich enough to display all these information. My current idea is to make every character a customized widget with such data embedded within.
This task can be quite huge if each Chinese character (there are approximately 5000 characters that are commonly used) has its own rich data format.
Any suggestions on how to approach this problem in an efficient manner in Flutter?
Thanks in advance!
There are a few ways to do this. Using widgets could definitely be an option, but that's probably going to cause you issues in the long run.
Let's break this into two parts:
1: Displaying the text
Instead of using widgets, I'd suggest using a RichText with many TextSpan children. You could create a custom class that accepts the string, splits it into characters, and puts each character in its own TextSpan. By using TextSpan.recognizer. You could then either use a TapGestureRecognizer with onTap to show the information when tapped if you don't need the position at which it was tapped, or onTapDown/onTapUp if you do (for example if you want to show a popup right where the click happened as opposed to something like a bottom sheet that comes up).
2: Showing the information
Because you're wanting to deal with a large amount of characters, I'd suggest not doing it all in code but instead handling the characters in some other sort of format that can easily be manipulated, for example JSON. That way you can do things like splitting the data it into blocks and loading them as needed, and/or getting them from a web server.
Your data could look something like:
{
"家": {
"pronunciation": "jia",
"audio": "path/to/sound.m4a",
"animation": "path/to/animation.gif"
},
...
}
You could theoretically even do things like start loading the pronunciation files when the character is first shown or when they click on it.
When the character is tapped, you could:
check if data in cache
load the data if needed from network/disk
open bottom sheet or popup displaying the pronunciation info + buttons for audio & drawing animation
I am trying to replicate the mobile tag-adding mechanism that tumblr has. I have included a picture of the screen I am talking about below.
I want to replicate the following features:
Chips are inline with text field. Text field resizes dynamically to either take the remainder of the line, or take up the next line if the content is too long
Text is turned into a chip when a comma is added (e.g. If I am typing "dog", and then I type "dog,", A "dog" chip will be created
Long chips cut off content with ellipses
Chips can be deleted with backspace
There is no text field underline decoration
Chips fill up row then wrap to next row (and entire container scrolls if there are too many rows to display simultaneously)
There are some libraries that already exist to allow a text input field with chips, but they have a lot of other features that I'm not interested in right now like the recommendation system etc, and generally just don't look the way I want with regards to multiple lines and text wrapping etc. If anyone knows how to replicate the example below, I would really appreciate it!
I am working on a site that will have very high international distribution and need to understand the maximum width of a like button in any of the available languages.
So far, the biggest Like button I can find is in Russian - http://cl.ly/Jmeb.
Is there a full specification list containing the size of the like button for each available language?
Well, the most robust way to design your site is to not impose tight limits on the size of the Like button. The Facebook Developers topic Internationalization says,
Avoid Layouts Relying on Precise Sizing
Try not to use layouts that depend on the precise onscreen sizes of pieces of text in the original language. For any piece of text, in some languages it is likely to be shorter and in some it will be longer (sometimes significantly so in either direction.) If you have sized your user interface elements such that your text just barely fits, your application will probably not work well in a language with longer words.
Similarly, the Facebook Developers topic Like Button says,
You may need to adjust the width of the Like button to accommodate different languages.
You found a Like button in Russian that is 110 pixels wide. Can your layout work with a button that is 1.5 times as wide? 2 times as wide? 5 times as wide? Then you are probably safe.
But the browser is retrieving they Like button image from Facebook when it displays your page, right? So even if we can give you a full list of the size of the Like button for each available language today, tomorrow Facebook could add another language which has a longer Like button.
That said, Facebook does give code for getting the Like button in any language you choose (see FAQ: How do I display the Like button in different languages?):
src="http://www.facebook.com/plugins/like.php?locale=fr_FR&...
Facebook also publishes an XML file listing the locales that Facebook supports. With a bit of Grep search/replace, we can generate an HTML page which displays Like buttons in all 76 locales listed today. Looking at the width of those buttons, we see that Irish localisation of the Like button is the widest at the moment, with 127 pixels. (On my system, the Like button in Malayalam comes up a bit wider at 169 pixels, but that's because I don't have a Malayalam font installed, so the button displays with missing-glyph boxes.)
So, it looks like the maximum width of a Like button in the languages supported at the moment 169 pixels wide. But, coding to this width is not what Facebook, or good internationalisation design, recommends. Instead, make your layout flexible, and able to cope with wider Like buttons in some locales.
In my iPhone app, my navigation bar titles were often too long for the page, causing them to truncate (I usually have a button either side of the title, so space is limited). I therefore created my own title labels with a hard-coded font size so the text would shrink accordingly. However, I now realise that this wont neccesarily look right when other languages are chosen.
What is the normal practice for this? Do people just accept a truncated title, or reduce the font size accordingly (for English), or enforce a very short title that will be short enough in all languages?
I don't think there's a magic solution here. You just need to pick shorter titles or accept the truncation. You can always put the full text in the display rather than in the title bar if necessary.
Based on feedback from some users, I wouldn't go down the route of using smaller text. (I'm basing this on a toolbar at the bottom of the screen rather than the title bar, but the same principle applies.)
I chose one title that is short enough for every language and display it regardless of what the view controller shows.
Apple shows as a title what the view controller shows: in the iPod app, for instance, when you select a playlist, the whole name is displayed. If it is too long, it gets truncated.
So I think it is ok to show a truncated title. You should not however make the text smaller as it will get too hard to read.
Thought it would be relevant to contribute to this discussion with a great solutoin that I came across in one of the apps I've been using.
https://itunes.apple.com/in/app/bookmyshow-movie-event-play/id405894842?mt=8
These guys animate the title left and right within the titleview's bounds, if the title text is too long. Looks neat and elegant without truncation, smaller text or other hassles.
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.