Vertical UIToolBar and also its UIBarButtonItem - objective-c

In my application i have one UIToolBar. When in portrait mode this toolbar is on top and is horizontal, but when the device is rotated this toolbar should be converted to vertical toolbar and should be place on left side. Also its subviews i.e 5 UIBarButtonItems should also be placed accordingly.
Does any one know the solution for this ?
I have read this for reference, But my tool bar should align itself according to the orientation. I am using iOS 6.

There is no built-in vertical menu feature (yet). There are 2 parts in your question:
Vertical UIToolbar:
You may restrict the device orientation and the toolbar will remain at the same location
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
(this will affect all views)
Or you can listen for orientation changes and rotate your toolbar accordingly using its transform property, e.g.
toolbar.transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI/2);
Rotated UIBarButtonItem:
If you have rotated the toolbar (case 2 above), items will rotate too.
If not, you need to rotate your items. Several post shows how to deal with the fact that as UIBarButtonItem does not extend UIView, it has no transform property (see here). In the end you will have again to listen for orientation changes and rotate the subviews of your toolbar, e.g.
for (UIView *view in toolbar.subviews) {
view.transform = CGAffineTransformRotate(CGAffineTransformIdentity, M_PI/2);
}
Of course apply the rotation related to your orientation (M_PI/2 or -M_PI/2).

I ran into this same issue, so I subclassed UIToolbar and made it into exactly what I wanted it to be.
Here's the GitHub link: https://github.com/fennelouski/NKFToolbar

Related

Setting UIScrollView's origin for pinch gestures

I'm creating a scroll view for displaying a very large view, and I need both scroll and zoom functionality (just like an image viewer). Here are the steps that I've taken:
In interface builder, I've put a scroll viewer to the view controller.
I've added a pinch gesture recognizer to the scroll viewer.
I've connected the gesture recognizer's action to the code to handle the gesture events.
When the view controller is loaded, I change my view's origin to the center (viewer is my scroll viewer): self.viewer.contentOffset = CGPointMake(384, 512);
In my code for the handler, I handled the event as such:
(startScale is 1.0 in the beginning)
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)sender {
if(sender.state == UIGestureRecognizerStateEnded){
startScale *= sender.scale;
}else{
float result = sender.scale * startScale;
self.viewer.transform = CGAffineTransformMakeScale(result, result);
}
}
When I run the app, the gesture is recognized and scaling works correctly, however, the whole view scales with respect to the 0,0 point of the screen (top left). I want it to scale with respect to the middle point that I'm applying the gesture, just as a natural pinch gesture for zooming into a photo.
I've also tried setting self.viewer.frame's origin, but nothing changed. I've searched about the problem and found these:
How to set a UIView's origin reference? (already tried)
https://stackoverflow.com/questions/13163279/pinch-punch-gestures-center (about my problem, but unanswered)
UIPinchGestureRecognizer for zooming and panning an image in xcode (looks like an overkill, too complicated for me, and I'm not sure if this would really help my situation)
How can I achieve natural pinching with my scroll view, what am I doing wrong?
Thanks,
Can.
Well, the answer to the problem is very simple: Remove the pinch gesture altogether. The benefit of using a UIScrollView is that it handles the panning/zooming internally, and you have to do nothing
Edit: To make sure the content is scaled properly, you are going to need a UIView (called contentView or whatever you want) where you put all the content, and then on the delegate method of your UIScrollView do this:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return contentView;
}
This should solve your problem
Edit 2: Also remember to set the minimum / maximum zoom scales for your UIScrollView

How to control nested scrollviews

In my iphone application I want to use 2 scrollviews and they have some images inside. Well, my question is when I scroll vertically on my first scrollview I want to explore the content of it however when I scroll horizontally I want to move to my second scrollview. I hope I explained clearly.
Well, I tried to use 3 scrollviews first of them located on the background, others are located on the first scrollview but I can only control the background scrollview or the others at once.
Is there a way to control first one horizontally and the others vertically.sorry for my english, hope it makes sense.
I have two recommendations.
1) Scrollviews can scroll horizontally and vertically - so you dont need two of them if you have content in a vertical direction and content in a horizontal direction. You can use one.
2) If for some reason you really do need 2, then you can detect a horizontal swipe by subclassing UIScrollView and switch to the other.
Remember that a UIScrollView will scroll in any direction that exceeds its contentSize. So all you need to do in the first case (1) is take the view that is inside say scrollview 2 (the horizontal scrollview) and put that view in the scroll view to the left or the right outside of the scrollviews viewport when the user scrolls they will see that view and can of course scroll vertically there as well.
If you use method 2 - make sure that the content size of scrollview one is at leat a few pixels more wide than the content size so that you can detect a horizontal swipe then invoke the coe to switch to your other scroll view. If you dont subclass UIScrollview to get the swipe you probably wont get the event. So do that add a little to the width of that view and then look for a value less than the left edge of the scroll view and switch to the other scroll view. You can do the same in reverse to go back to the previous scrollview.
I hope this helps - sorry no code at the moment, but I do have code working on iOS and OSX that does this.
You can distinguish both UIScrollView via if statement
Set delegate of both UIScrollView
Then compare your scrollView in its delegate method. You can change your delegate method according to your requirement -
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(firstScrollView == scrollView)
{
//Do your work for firstScrollView
}
if(secondScrollView == scrollView)
{
//Do your work for secondScrollView
}
}
try to do in delegates methords
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
set some conditions like
if(myScroll1)
{
//scroll vatical.
}
if(myScroll2)
{
//scroll horizontal.
}
this is not complete code this is an idea Best of luck..

How to use NSScrollview?

I can't figure out how to actually use NSScrollview. I dragged the scroll view object onto an NSWindow in the interface builder. I then dragged some NSButtons onto the scroll view. My question is:
How do I actually make it scroll down, for example, 2x the original height?
Of course the user can scroll automatically using their UI. I assume what you want to do is to scroll programmatically.
A bit of background: An NSScrollView has a documentView, which is the underlying view that the scroll view shows a part of, and a clipView, which is the view that is shown on the screen. So the clip view is like a window into the document view. To scroll programmatically you tell the document view to scroll itself in the clip view.
You have two options on how to scroll programmatically:
- (void)scrollPoint:(NSPoint)aPoint –– This scrolls the document so the given point is at the origin of the clip view that encloses it.
- (BOOL)scrollRectToVisible:(NSRect)aRect –– This scrolls the document the minimum distance so the entire rectangle is visible. Note: This may not need to scroll at all in which case it returns NO.
So, for example, here is an example from Apple's Scroll View Programming Guide on how to scroll to the bottom of the document view. Assuming you have an IBOutlet called scrollView connected up to the NSScrollView in your nib file you can do the following:
- (void)scrollToBottom
{
NSPoint newScrollOrigin;
if ([[scrollview documentView] isFlipped]) {
newScrollOrigin = NSMakePoint(0.0,NSMaxY([[scrollview documentView] frame])
-NSHeight([[scrollview contentView] bounds]));
} else {
newScrollOrigin = NSMakePoint(0.0,0.0);
}
[[scrollview documentView] scrollPoint:newScrollOrigin];
}

Possible to manually rotate UIPopoverController's view?

The view system in my app is highly customized and uses a number of views that are manually rotated from portrait to landscape based on user interactions (the rotation is done by applying an affine transform to the view/layer).
I want to present a popover inside one of these rotated views, but the orientation of the popover always appears relative to the orientation of the device (i.e., not relative to the view). I'm guessing the answer is no, but just in case someone has a clever idea: is there any way to manually rotate the view that is presented by UIPopoverController?
Sean, I just tested it for kicks, yes it works.
It has to be done (in my case at least) in viewDidAppear (if done in viewWillAppear, it gets knocked back to the original setting.)
This worked just fine (just tested now) to have a popover at a 90 degree angle. i.e in my case my main view is in portrait mode and the popover is turned 90 deg.
self.navigationController.view.superview.superview.transform = CGAffineTransformMakeRotation (M_PI/2.0);
Are you trying to rotate the popover or just the content shown in the popover? You can control some of the former by setting which arrow orientations are possible. I'm interested in the latter, and it seems to work just by grabbing the content view controller. E.g.:
aPopoverController.contentViewController.view.transform = CGAffineTransformMakeRotation(M_PI);
DISCLAIMER: If you're at all interested in trying to get your app into the store, this code is almost certainly grounds for rejection. It dives into UIKit's private API's which is a big no-no as far as apple is concerned.
#RunningPink had the right idea. Depending on how the view hierarchy is set up, the popover may be back up farther than two superviews. The popover itself it an instance of the (private) class _UIPopover (at least in iOS 5). You can find this view by doing:
UIView *possiblePopover = popoverController.contentViewController.view;
while (possiblePopover != nil) {
// Climb up the view hierarchy
possiblePopover = possiblePopover.superview;
if ( [NSStringFromClass([possiblePopover class]) isEqualToString:#"_UIPopoverView"] ) {
// We found the popover, break out of the loop
break;
}
}
if (nil != possiblePopover) {
// Do whatever you want with the popover
}
In doing this, I found that transforming the view often ended up making the popover look blurry. I found the reason was that the popover's superview was an instance of another private class called UIDimmingView which is responsible for accepting touches outside of the popover and causing the popover to dismiss. Performing the rotation on the dimming view removed the blurriness I was seeing in the popover.
However, transforming the dimming can result in weirdness where certain parts of the window are not "covered" by the dimming view so the popover will not dismiss if these parts of the window are tapped. To get around this, I applied the rotation to the dimming view, reset the dimming view's frame to cover the screen, and then translated the popover view into place.
if (nil != possiblePopover) {
// Found the popover view
CGAffineTransform rotation = CGAffineTransformMakeRotation(-M_PI_2);
CGAffineTransform translation = // Whatever translation in necessary here
// Rotate the UIDimming View and reset its frame
[possiblePopover.superview setTransform:rotation];
[possiblePopover.superview setFrame:CGRectMake(0, 0, possiblePopover.superview.frame.size.height, possiblePopover.superview.frame.size.width)];
// Translate the popover view
[possiblePopover setTransform:translation];
}

Stop UIToolbar from Disappearing in Landscape Orientation - iPad

Not sure why this happens or how to stop it, my UIToolBar on the details viewcontroller is only visible during portrait view. I want it visible at all orientations. How do I do that? Thank you.
I encountered the same problem by just dragging a UIToolBar on to my view and docking it on the top of the window. It showed up in landscape but not portrait. Interface Builder - at least the one embedded in Xcode 4 - doesn't seem to do the right thing with the resize masks.
While Kshitiz's answer above will work, it has a couple of flaws. As coded, it does not support all four orientations. More importantly, it's not resolution independent.
A better solution is briefly described in enamrik's comment, so credit should go to him/her. Here are the steps:
Select the tool bar in Interface Builder.
Open the Size inspector.
In the Autosizing box, select the left, right and top "i-beams" on the exterior of the square. This keeps the position of the toolbar fixed relative to the sides of the view when the view is resized.
Inside the Autosizing square, select the horizontal line with arrows on both ends. This causes the size of the toolbar to change in sync with the parent view.
in your this function of view controller reset view frame bro
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight) {
self.view.frame = CGRectMake(0, 0, 703,768);
} else {
self.view.frame = CGRectMake(0, 0, 768, 1024);
}
return YES;
}
and your tool bar frame too
good luck
Faced the same problem when I add UIPickerView programmatically and add UIToolBar for the PickerView. Just need to add [.flexibleWidth,.flexibleHeight] for the UIPickerView. eg:-
let statTypePicker = UIPickerView()
And then add
self.statTypePicker.autoresizingMask = [.flexibleWidth,.flexibleHeight]