Implementing 'About' view in iOS using Xamarin Studio - ios

How do I autosize Labels so they contain all the text, but don't take up any more space then necessary and stay vertically spaced the same whether the user is in portrait or landscape mode?
I am trying to implement a simple control that displays information about my app in paragraph form. It will have Headings, and Paragraphs. I am having problems correctly positioning things relative to each other and have them auto adjust as the user rotates their device and changes orientation.
In the example below, I have 4 labels. 2 are for headings and are bolded with larger font, 2 have standard font, but are long and have lots of text. I want to be able to have all the text visible on each label and have none cut off. I also, want all the labels as close as they can be to each other. So, their containing rectangles have to change based on all of the other label's height. So when I change from landscape to portrait orientation, the paragraphs may take 8 lines instead of the 3 lines it takes in landscape mode. I want the controls to shift to have the same amount of Vertical white space between each of them.
Here is a sample:
About this program
Thank you for downloading this app. It is designed to do some
wonderful things and will make all your wildest dreams come true.
Help
In order to use this program, use the tab bar at the bottom of the
screen to select what you want to do. When the view opens, slide the
items across the view until you are done.

I'll quote Mattt Thompson:
This is the type of thing TextKit was created for. Check out Wenderlich's tutorial for an easy start.

I followed the advice in Jason's comment and it works like a charm:
Try using a UIWebView and embedded HTML for your content. – Jason Oct
30 at 19:23
Thanks Jason !!

Related

swift 4 and Xcode autoLayout and UIImageview as Button

I am working on auto layout and making those UIIMages as Button.
I would like to make those button to be clicked and switch the images
as well as showing some words in the label.
In this case what should I do?
In addition, as it is shown, the auto layout ratio is different only from the iPhone SE. In. this case What should I consider?
Many thanks,
The first thing you need to learn is auto layout. Start with basic Always go with Apple's doc first
This one I likes he is good and you will also find how to use buttons as image view, using card game example, check other tutorials also very helpfull.
Stanford university autolayout by Michel Deiman
As far, your question just gives your label Horizontal in the container constraints(open storyboard in the right bottom third from last (allin) click on it popUp will open), and 20 bottom to the buttons and it will be in the centre. Every elements need x,y height and width so it knows exactly where to place, so you also need to give constraints to the buttons, Learn stackView to understand how to place your button without giving many constraints to each button and stack view will handle it for you, try hide and show to one of the button and magically stack view will adjust all adjustment. I suggest before staring Do read apple's doc first.
And Your question is too broad to answer, so read and try adding different constraints based on your need and ask a specific question(after trying by yourself) like why this label getting cut what constraints should i add so people know exactly what you want to achieve, people are always ready to help, just ask the right question.
happyCoding

How do you make a vertical text UILabel and UITextView for iOS in Swift?

If you came to this question based on the title but are not interested in Mongolian, you might be looking for this Q&A instead:
Swift: How can you rotate text for UIButton and UILabel?
I've been learning Swift in order to develop iOS apps for traditional Mongolian. The problem is that traditional Mongolian is written vertically from top to bottom and from left to right. My question is how do I display text vertically and still have line wrapping work?
If you stay with me for a minute, I'll try to explain the problem more clearly. Below is an image of the kind of text view I would like to achieve. In case the foreign script throws you off, I have included English text that follows the same pattern. In fact, if the app has any English text to display, this is how it should look.
For a simple one-line UILabel, a 90 degree clockwise rotation would work. However, for a multi-line UITextView I need to deal with line wrapping. If I just do a plain 90 degree rotation, the first thing written will end up being on the last line.
So far I have made a plan that I think can overcome this problem:
Make a custom font in which all of the letters are mirrored vertically.
Rotate the text view 90 degrees clockwise.
Mirror the text view horizontally.
That should take care of the text wrap.
I can do the mirrored font. However, I don't know how to do the Swift coding for the rotation and mirroring of the UITextView. I've found the following links that seem to give hints to parts of the solution, but they are all in Objective C and not in Swift.
How to rotate sub-views around their own centres?
Rotate UIView around its center keeping its size
iOS: Mirror content on screen
Mirroring UIView
There are traditional Mongolian apps in the app store (like this and this) but I haven't found anyone yet who is sharing their source code, so I don't know what they are doing behind the scenes to display the text. I plan to make my code open source so that it is not so hard for others in the future to develop apps for the several million people who read traditional Mongolian. Any assistance you can give to this endeavor would be much appreciated, not just by me but also by the Mongolian people. Even if you don't know yourself, upvoting this question to make it more visible would help.
Update
#sangonz's answer is still a great answer, but I temporarily unmarked it as the accepted answer because I just couldn't get everything to work. Specifically:
Enabling scrolling (either by embeding the custom view in a scrollview or by subclassing UIScrollView). In the github project, #sangonz said this should be easy, but it wasn't for me.
Getting a relayout (rather than stretching) of the word lines on an orientation change. I think this shouldn't be too hard to solve with a little more research.
Why don't the text lines go all the way to the edge of the view? There is a big gap at the bottom.
How to unlink the NSTextStorage of the custom vertical view from the other UITextView. (see this question)
Up to this point I have been using the original method I proposed above, but what I really want is to get something like what #sangonz proposed working.
I am also now considering alternate methods like
Using Core Text, Disadvantage: it feels like reinventing the wheel
Using WebKit, Disadvantage: Apple no longer uses WebKit for their UITextView
Edit: This is how I finally did it.
Here's a very basic implementation in my GitHub: Vertical-Text-iOS.
Nothing fancy, but it works. Finally I had to mix TextKit and image processing. Take a look at the code. It involves:
Subclassing NSTextContainer to get the right text dimensions.
Creating a custom UIView to render the text applying affine transformations to each line and rendering using NSLayoutManager to keep all TextKit features.
TextKit way
The proper way to keep all native text benefits (e.g. highlighting, selection...) is to use standard TextKit APIs. The method you are proposing would break all that or would possibly result in strange behaviour.
However, looks like TextKit in iOS does not support vertical orientation out-of-the-box yet, but it is prepared for that. As a side note, in OS X it is somewhat supported and you could call textView.setLayoutOrientation(.Vertical), but it still has some limitations.
The NSTextLayoutOrientationProvider protocol defines an interface
providing the default orientation for text laid out in a conforming
object, in absence of an explicit NSVerticalGlyphFormAttributeName
attribute. The only UIKit class that implements this interface is
NSTextContainer, whose default implementation returns
NSTextLayoutOrientationHorizontal. An NSTextContainer subclass that
handles vertical text could set this property to
NSTextLayoutOrientationVertical to support the custom layout
orientation logic.
Source: UIKit > NSTextLayoutOrientationProvider Protocol Reference for iOS
In conclusion, you should start subclassing NSTextContainer, and you will have to deal with NSLayoutManager and NSTextContainer a lot.
Custom image processing way
If, on the other hand you decide to follow your custom text rendering I suggest the following approach.
Render the normal text to a hidden layer with a normal font. Give it the correct size to its bounding box.
Get the text properties, mainly text height and line spacing.
Process the image drawing each line in reverse order from bottom to top as you can see in the image below. You should get a new CGImage as a result.
Rotate the image creating a UIImage and setting the correct UIImageOrientation value.
Insert that image into a UIScrollView that only allows horizontal scrolling.
Beware this method renders the whole text, so don't use it for very long texts. If you need to do that, you will need to consider a tiling approach. Watch WWDC 2013 > 217 - Exploring Scroll Views on iOS 7.
Good luck!
Update: (image from github project)
If you're going to rotate the text I would suggest using a right-to-left layout so that you can skip the mirroring step (and just rotate the other way).
You should be able to just set the label/textview's transform property:
view.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(CGFloat(-M_PI_2)), view.bounds.width, view.bounds.height)
You need to translate after you rotate because the view rotates around its origin (in the upper left).
The good news is that gestures and taps are transformed at the same time the pixels are, so controls continue to work the way you expect them to.

Laying out subviews in a UITableViewCell dynamically

This is the most complicated UI related problem I've come across yet. I've been trying to find a solution for literally weeks but no avail. Let em explain.
In this app I'm working on, I need to display a certain list. It's actually a schedule. Here's how it should look like,
The fields circled by red circles don't change. To explain what change means I have to show you this.
Its a set of filters which the user can show/hide certain fields and the ones that are circled in the first image are static ones. They can't be toggled on and off.
Now the problem arises with the ones that can be toggled. Here's what it looks like if you turn off the Show Actions flag.
A new label with a blue background replaces the bottom one you can see in the first image.
Here's another one where you disable Show Time option and the time labels are gone (yes it affects only for some. Its expected).
If this filter list were an option list, it would have been easy. Just create a custom cell for each option and you're good to go. But unfortunately the user is able to toggle multiple filters! For example the user can turn off both Show Actions and Show Time and it'd look like the last image but the bottom label would have the blue label in the third image.
To top it all off, the cells' height is dynamic. In iOS 8 creating self resizing cells are easy enough from the IB when you could just add auto layout constraints and done.
But it seems to me that creating these cells from the IB isn't an available option to me. Simply because there are way too many filter combinations a user can make. So the cell's subviews need to adjust to it.
My question is how can I create a dynamic cell like that? My best guess is through code, right? I haven't written my UI in code before so I tried creating a test project to familiarize myself with it. But the problems I'm facing is setting fixed frame sizes makes the dynamic nature obsolete. And how can I move a view to fill up a removed view's space (Last image. Time labels are gone so the name and the id labels move to the left to fill that space).
I know this question is a little too broad. I'm not asking for a straight answer either. I'd really appreciate some pointers, or even a better suggestion on how to approach this because I'm truly at the rock bottom on this issue.
Thank you.
It's hard to give you any precise help since your question is so broad. First, I would recommend watching the 3 videos on Auto Layout from the WWDC 2012 (sessions 202, 228, and 232).
To answer your one example, how to move a view to replace a view that's removed. You would need to make two left edge constraints from the view with the text (Kund Alof...). One with a constant of 0 to the time label with a priority of 1000 (that's the default), and another to the left edge of the cell, also with a constant of 0, but with a lower priority, say 900. As long as the time label is present, the constraint to it will determine the position of the text label, but when it's removed, the lower priority constraint to the left edge will take over and move the label over to the left edge.

RichText label or 'flow' layout for text in iOS (Xamarin/MonoTouch)

I am trying to repduce a similar sort of layout as in the screenshot below from the Digg app..
Notice that each list entry has a title in bold followed by the source, posted time and finally if there is enough space the start of the description line.
The question is what is the best way to achieve this in iOS? With some posts having longer titles than others I cannot simply say that the title label is 40px high and then place the Source label at 45 as the title will sometimes be longer and sometimes shorter.
Do I have to calculate the height of the label based on its contents before arranging the layout or is there some better way of doing this in iOS so that the views 'below' are automatically moved down?
Another alternative would be some sort of rich text label that I could add all the text to and have it automatically wrap round moving the later text down but I cannot find any sort of control in standard iOS / Xamarin (MonoTouch).
Any pointers would be greatly appreciated?
If you are using a storyboard the simplest way to achieve this result is to define different prototype cells. For example, you could define four different prototype cells, each one with a different layout like those shown in the example picture you provided. You can dequeue the appropriate cell based on the content you want to display so there is no need to adjust the layout in the code.
If you are doing everything in code, it's a lot more complicated since you have to build your own "layout engine" to adjust size and position of the views in your cell. You can have a look at XibFree or use MonoTouch.Dialog as suggested in the comments.

iOS (iPhone only): Horizontal page scroll, where the scrolling page doesn't take up the whole screen

I am trying to achieve horizontal page scrolling effect (partial view, not of the entire screen scrolling), like in the HGPageScrollView component.
I am a fairly novice iOS programmer, and I am having difficulty finding the parts of the code which provide just the horizontal scrolling with the swipe gesture. So I am looking for any help, either some sample code, or pointers to the code in the HGPageScrollView, which provide just the horizontal scrolling functionality (i.e. not even the UIPageControl dots at the bottom, just the vanilla scroll).
I am only looking for an implementation which works in iPhone landscape orientation, if that makes it any easier.
Why I am not using HGPageScrollView:
It is not ARC compliant.
It does way more than I need it to, I am just looking for the scrolling.
Consequently, it is proving quite difficult for me to find where to remove all the features I do not need, like clicking on page to change the scrolling mode to full screen (HGPageScrollViewModePage)
I would like to use this as an incentive to learn more about the components available in cocoa-touch, and roll my own implementation.
I think this question might be suggesting the solution, but I do not know how to implement it. I guess I don't fully understand it, as there aren't enough details for my novice skills to go on.
Use a UICollectionView and set the pagingEnabled property to YES.
If you want to do complex layouts of the items (like in your example above where items are split on both sides of the screen) you may want to provide your on UICollectionViewLayout: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewLayout_class/Reference/Reference.html#//apple_ref/occ/cl/UICollectionViewLayout

Resources