Is there a ways to adjust the width of the padding between Cocoa Touch UITabBar buttons? I'm working on an iPad project and I would like to reduce the padding between buttons for a slightly tighter look. Am I out of luck?
You could take a close look at TabBarKit and see if it suits your requirements. It doesn't explicitly mention that you can adjust spacing etc, but at least the code isn't a black box which would enable you to see if adding such functionality is within the realm of possibility.
Related
I would like to create a control for Apple Watch (using WatchKit) that resembles the iPhone UISegmentedControl.
Has anyone managed to achieve this on Apple Watch already?
I followed the suggestion of a user and used buttons and custom background colours to achieve this. However the issue I got now is that they do not align horizontally. Any way to do so?
Place your buttons in group with horizontal layout, make their widths relative to container with 0.5 value. Also you can set zero cornerRadius for buttons.
Just add your controls into WKInterfaceGroup,set its layout to Horizontal and tweak controls width in Interface Builder.Set spacing explicitly to 0 to override default value(2 pts).Here is the screenshot that illustrates the result.
You can group your buttons as Vladimir described if you really want to create a segmented control. However, if you do, you should probably use a shorter label than "Standby" for the third option, so that your tap targets can all have a consistent size.
Also, you might consider reworking your UI in such a way that you can eliminate the third option, be more explicit about what you're controlling, and use built-in controls with larger targets. For example, would something like this be possible?
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.
I have UIScrollView in which UIImageView is held like on the screenshot:
My problem appears when I zoom and instead of being able to scroll only in the area of my image (subview of scroll view) I'm able to scroll around the original size so I get a lot of white space around my image which isn't what I want. You can see what happens on the screenshot below:
I wonder what should I update to keep my scrolling area only the size of the image?
After some research, some trials and errors I've finally achieved what I was planning to do.
First of all, I wanted to use only autolayout with IB which sure can be done but with some effort. After some digging I've found this technical note which by "Pure Auto Layout Approach" understands adding contraints in code but I was aiming at only IB which led me to this simple but beautiful solution called ios-imagescroll. After investigating this code with joy that I've finally found solution I came with some error but only on iOS 8 devices... iOS 7 worked like charm out of the box.
I assume that due to big changes in iOS 8 autolayout is more strict and you must be 100% sure what you want to accomplish. It turned out that this slight change MATTERS on iOS 8:
Of course, this bug, fix (call it whatever you like) was fixed by experimenting with everything but I guess that UIScrollView's content view (in that case UIImageView) must be the first item in constraint.
[yourScrollView setContentSize:CGSizeMake(yourScrollView.size.width, yourImage.frame.origin.y + yourImage.frame.size.height+35 )]; //let's say just 35 ...
yourImage may have x,y origins like (0,0) [I see a lot of space above it, so I assume you have set other values for x,y]
In our application we are showing the segmented control with dynamic segments.
If number of segments is 2-3 we have no issue, but if number of segments is 5 or more than that then the text in segment is not readable.
See the above image.
So, what is the alternate way to resolve this issue?
There are a couple of solutions.
You could use a UIPickerView instead of a UISegmentedControl
You could show three segments, where the first two segments are the most often used segments, and touching the third segment shows a UIPickerView with all the options.
You could embed the UISegmentedControl in a UIScrollView. Make sure to size your segmented control in a way that shows that it is indeed scrollable.
Which one fits best depends on your app, and what is the actual use of those segments.
It's hard to answer this question on a general basis. Apple's Human Interface Guidlines may be a good reference for this kind of issues.
The best Solution is that add ScrollView in you view controller and add UISegmentController to UIScrollView and give fix size of your segment button and change size of UISegmentController Base on total numbers of button and also change content size of UIScrollView base on UISegmentController.
try setting font size for the test to be smaller, that ways, the text will be more visible.
However, if your number of segments keep increasing, that wouldn't be a solution
By default WP7 buttons are surrounded by a black space of 5ish pixels. I'd like to remove this, but I've tried setting the Margin, BorderThickness, Padding properties to be a Thinkness of zero, but this seems to have no effect on this mysterious space. Any clues what exactly this spaces is and how I might get rid of it.
Thanks,
Robert
This border is specifically added to increase the size of the button as a touch target. Having this padding makes it easier for people to be sure that they are touching the control they are aiming for.
If you are trying to remove this to fit more controls on the page be aware you're probably making it easier for users to accidentally tap the wrong control.
If you really must do this you must retemplate the button control.
The only difference you need to make to the default template (you can get a copy of this from Blend) is to change the margin on the controller from
<Border ... Margin="{StaticResource PhoneTouchTargetOverhang}">
to whatever value is appropriate for you.
Please also note that by changing this value you're likely to create issues for yourself when smaller screen devices are introduced.