Basically, this is what happens when I click on the left menu button.
http://i.stack.imgur.com/g7uq6.png
I want it to appear under the status bar and not to overlap it.
Here's the code:
HomeViewController.m
-(void)menuBarButtonItemClick{
mJUserAccountMenuViewController = nil;
mJUserAccountMenuViewController = [[MJUserAccountMenuViewController alloc] initWithNibName:#"MJUserAccountMenuViewController" bundle:nil];
mJUserAccountMenuViewController.delegate = self;
[self presentPopupViewController:mJUserAccountMenuViewController animationType:MJPopupViewAnimationSlideLeftRight];
}
mJUSerAccountMenuViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
leftMenuArrayy = [StaticDataCollection getSharedInstance].accountMenuArray;
backTOHomelabl.font = FONT_APP_DEFAULT_FONT;
backTOHomelabl.textColor = COLOR_WHITE_COLOR;
if (IS_IPHONE_5_SCREEN) {
[self.view setFrame:CGRectMake(0, 0, 250, 568)];
} else {
[self.view setFrame:CGRectMake(0, 0, 250, 480)];
}
}
If you are using storyboard and AutoLayout, you can set the top of menu equals top layout guide.
If you're using xib, you can set iOS 6/7 Delta to plus or minus y offset 20(Status bar's height).
If you set layout by code, you have to check the version of iOS. For example:
if([[[UIDevice currentDevice] systemVersion] integerValue] >= 7)
{
// set the subviews' offset +20px(statusBar's height)
}
Related
how can I add a UISwitch to a specific UIScrollView? As I guess it can be done with a tag, but I am having difficulties.
EDIT: The problem was solved in the usual way, lol
My example code with UIScrollView and UISwitch:
#implementation NSPage {
UIScrollView *scrolled;
UISwitch *switchPage;
NSInteger *keyS;
}
NSPage *page = [[NSPage alloc]init];
Here i am creating a UIScrollView and UISwitch:
-(id)initPage:(NSString *)titleScroll keyScroll:(NSInteger)keyScroll_ {
keyS = keyScroll_;
scrolled = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 180, 110)];
scrolled.tag = keyS;
scrolled.backgroundColor = [UIColor grayColor];
[window addSubview:scrolled];
}
//get scroll tag
-(NSInteger)getScrollKey {
return scrolled.tag = keyS;
}
//UISwitch
-(id)initSwitch:(NSString *)title_ keySwitch:(NSInteger)keySwitch_ {
scrollSwitch += 40;
switch_ = [[UISwitch alloc]initWithFrame:CGRectMake(15, scrollSwitch - 40, 40, 40)];
switch_.tag = keySwitch_;
if([self getScrollKey] == switch_.tag) {
[scrolled addSubview:switch_];
}
}
#end
Everything seemed to be fine, but when I add a scrolls and switches, then my UISwitch is not displayed:
page = [[NSPage alloc]initPage:#"test page" keyScroll:256];
page = [[NSPage alloc]initSwitch:#"test" keySwitch:256];
What could be my mistake, how can I add a UISwitch to a specific UIScrollView? I'm a beginner, Thanks for the help anyway
if([self getScrollKey] == switch_.tag) {
This line does nothing take it out
while presenting the search controller i am setting the showScopeBar property to hide or show the scope bar
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
NSMutableArray *scopeArray = #[#"All"].mutableCopy;
UISearchBar *searchBar =_searchController.searchBar;
if (![labelDepartmentSelection.text isEqualToString:#"Department"]) {
[scopeArray addObject:#"Department"];
}
if (![labelJobSelection.text isEqualToString:#"Job"]) {
[scopeArray addObject:#"Job"];
}
searchBar.scopeButtonTitles = scopeArray;
searchBar.showsScopeBar = scopeArray.count>1;
[searchBar layoutIfNeeded];
NSArray *subviews = searchBar.subviews;
if([[UIDevice currentDevice].systemVersion floatValue]>=7.0) {
//Get search bar with scope bar to reappear after search keyboard is dismissed
UIView *scopeBar = [subviews.firstObject subviews].firstObject;
[scopeBar setHidden:NO];
CGRect frame = scopeBar.frame;
frame.origin.y = frame.origin.y = 64.0;
scopeBar.frame = frame;
}
[searchBar layoutSubviews];
[searchBar sizeToFit];
[serviceOptionTableView setContentInset:UIEdgeInsetsMake(scopeArray.count>1?44:0, 0, 0, 0)];
serviceOptionTableView.tableHeaderView = searchController.searchBar;
}
and when i simply hide and show the scope bar base on the scope titles i want it giet distorted
here is the case for this
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
NSMutableArray *scopeArray = #\[#"All"\].mutableCopy;
UISearchBar *searchBar =_searchController.searchBar;
if (!\[labelDepartmentSelection.text isEqualToString:#"Department"\]) {
\[scopeArray addObject:#"Department"\];
}
if (!\[labelJobSelection.text isEqualToString:#"Job"\]) {
\[scopeArray addObject:#"Job"\];
}
searchBar.scopeButtonTitles = scopeArray;
searchBar.showsScopeBar = scopeArray.count>1;
\[serviceOptionTableView setContentInset:UIEdgeInsetsMake(scopeArray.count>1?44:0, 0, 0, 0)\];
}
this is the image of case 2
The issue should fix itself if you remove the line:
searchBar.showsScopeBar = scopeArray.count>1;
Setting the showScopeBar property has a weird effect for some reason. Removing it allows the default animation behaviour without any issues.
In my navigation bar, I have a magnifying glass icon that brings up a search bar. I'm not using a UISearchDisplayController, so I opted to build my own UINavigationItem and then push it over the standard UINavigationItem using pushNavigationItem.
The problem is that the UINavigationItem seems to be pushed around 8 pixels to the right. This causes the cancel button (with localized text 'Annuleren') to be really close to the edge of the screen.
I tried inspecting the self.mySearchBar.bounds at runtime, but the origin is 0,0. I've played around a bit with AutoLayout and programmatically added constraints, but I haven't been successful. I hope it's possible without AutoLayout.
This is my code:
- (IBAction)displaySearchBar:(id)sender {
if (!self.mySearchNavigationItem)
{
self.mySearchNavigationItem = [[UINavigationItem alloc] initWithTitle:#""];
self.mySearchNavigationItem.hidesBackButton = YES;
self.mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
self.mySearchBar.showsCancelButton = YES;
self.mySearchBar.delegate = self;
[self.mySearchBar sizeToFit];
[self.mySearchBar setPlaceholder:#"Zoeken..."];
UIView *barWrapper = [[UIView alloc]initWithFrame:self.mySearchBar.bounds];
[barWrapper addSubview:self.mySearchBar];
self.mySearchNavigationItem.leftBarButtonItem = nil;
self.mySearchNavigationItem.backBarButtonItem = nil;
self.mySearchNavigationItem.titleView = barWrapper;
UIButton *cancelButton;
UIView *topView = self.mySearchBar.subviews[0];
for (UIView *subView in topView.subviews) {
if ([subView isKindOfClass:NSClassFromString(#"UINavigationButton")]) {
cancelButton = (UIButton*)subView;
}
}
if (cancelButton) {
[cancelButton setTitle:#"Annuleren" forState:UIControlStateNormal];
}
}
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
NSTimeInterval delay;
if (self.tableView.contentOffset.y >1000) delay = 0.4;
else delay = 0.1;
[self performSelector:#selector(activateSearch) withObject:nil afterDelay:delay];
}
try:
self.navigationController.navigationBar.barTintColor = self.mySearchBar.barTintColor;
if that doesn't work, you can add an underlay view to the navigation controller that is the color you would like. this may be useful: Get the right color in iOS7 translucent navigation bar
After searching for many hours, I gave up and went for a dirty fix. I'll leave it open for a while, in case someone knows why my searchbar is moved 8 pixels to the right.
Right before showing the UINavigationItem, I move the whole UINavigationBar to x-coordinate -8.
self.navigationController.navigationBar.frame = CGRectMake(-8.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
And then on the cancel button click, I move it back to x-coordinate 0.
- (IBAction)cancelSearchBar:(id)sender {
[self.navigationController.navigationBar popNavigationItemAnimated:YES];
self.navigationController.navigationBar.frame = CGRectMake(0.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
}
I'm creating an app that can slide between pages of a book, left and right (covering or revealing like a card deck), and sliding up and down will either slide down (and cover) a settings page, or slide up (and reveal) to detailed info on the book.
Essentially, its a "card deck" Sliding functionality, similar to this project https://github.com/sweetmandm/CardSliderView-for-iOS which I'm considering using, however I require BOTH vertical AND horizontal "card deck" sliding capability.
To give you another example of the slide/left cover/reveal effect I'm looking, take a look at the new CNN app, where you can slide between articles.
I've also considered using UIPageViewController, however this does not support the "Slide and Reveal / Slide and Cover" transition I'm looking for, rather only a "Slide Over Left or Right" transition, so I would have to hack it somehow and use multiple UIPageViewControllers, one on top of the over, to allow the "reveal and cover" effect to work, using just the gestures from the UIPageViewController to allow the user to swipe.
I'm familiar with the directionalLockEnabled property on UIScrollview, however I'm wondering still what is the overall best approach to get the effect I'm looking for, one that will support both vertical and horizontal, UIScrollView? UIPageViewController? Nested UIScrollviews? Instead of playing around with the directionalLockEnabled property? Something Else?
What would be the best way to achieve the exact user experience I'm looking to provide?
Ok, I found a solution to my own question, using nested UIScrollViews. I also added a very rough solution as project to github: https://github.com/cohen72/InfiniteDeckScroller.
For the horizontal scrolling, I have three horizontal scroll views, one nested into the other. UIScrollview is automatically handling the proper scrolling of each. Depending on the content offset and which scrollview is being scrolled, I know how to "re-arrange/re-order" the nested scrollviews.
Here is a snippet of the solution I came up.
This particular solution allows sliding up to reveal, however I did not yet implement the sliding down to cover, however doing so would use the same approach as the horizontal solution.
#define BOTTOM 1
#define MIDDLE 2
#define TOP 3
#define VERTICAL_SUB 4
- (void)viewDidLoad{
[super viewDidLoad];
UIScrollView *scroll1 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
UIScrollView *scroll2 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
UIScrollView *scroll3 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
UIScrollView *scroll4 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scroll1.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
scroll1.tag = BOTTOM;
scroll1.pagingEnabled = YES;
scroll1.bounces = NO;
scroll1.delegate = self;
[scroll1 addSubview:[self labelForScrollView:scroll1 withBgColor:[UIColor redColor]]];
[scroll1 setContentOffset:CGPointMake(0, 0)];
scroll2.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
scroll2.tag = MIDDLE;
scroll2.pagingEnabled = YES;
scroll2.bounces = NO;
scroll2.delegate = self;
[scroll2 addSubview:[self labelForScrollView:scroll2 withBgColor:[UIColor orangeColor]]];
[scroll2 setContentOffset:CGPointMake(0, 0)];
scroll3.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
scroll3.tag = TOP;
scroll3.pagingEnabled = YES;
scroll3.bounces = NO;
scroll3.delegate = self;
[scroll3 addSubview:[self labelForScrollView:scroll3 withBgColor:[UIColor yellowColor]]];
[scroll3 setContentOffset:CGPointMake(320, 0)];
scroll4.contentSize = CGSizeMake(self.view.frame.size.width * 1, self.view.frame.size.height * 2);
scroll4.delegate = self;
scroll4.bounces = NO;
scroll4.pagingEnabled = YES;
scroll4.alwaysBounceVertical = NO;
scroll4.tag = VERTICAL_SUB;
[scroll4 addSubview:scroll1];
[scroll1 addSubview:scroll2];
[scroll2 addSubview:scroll3];
[self.view addSubview:scroll4];
}
- (UILabel*)labelForScrollView:(UIScrollView*)scrollView withBgColor:(UIColor*)color{
UILabel *lbl = [[UILabel alloc] initWithFrame:scrollView.bounds];
lbl.textAlignment = NSTextAlignmentCenter;
lbl.backgroundColor = color;
lbl.text = [NSString stringWithFormat:#"ScrollView: %d", scrollView.tag];
return lbl;
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
NSLog(#"content offset: %f, tag: %d ", scrollView.contentOffset.x, scrollView.tag);
UIScrollView *newMiddleScrollView, *newBottomScrollView, *newTopScrollView;
// swipe left
if (scrollView.contentOffset.x == 0 && scrollView.tag == TOP) {
newMiddleScrollView = (UIScrollView*)[self.view viewWithTag:TOP];
newTopScrollView = (UIScrollView*)[self.view viewWithTag:BOTTOM];
newBottomScrollView = (UIScrollView*)[self.view viewWithTag:MIDDLE];
}
// swipe right
else if (scrollView.contentOffset.x == 320 && scrollView.tag == MIDDLE) {
newMiddleScrollView = (UIScrollView*)[self.view viewWithTag:BOTTOM];
newTopScrollView = (UIScrollView*)[self.view viewWithTag:MIDDLE];
newBottomScrollView = (UIScrollView*)[self.view viewWithTag:TOP];
}
else {
return;
}
newMiddleScrollView.tag = MIDDLE;
newBottomScrollView.tag = BOTTOM;
newTopScrollView.tag = TOP;
newBottomScrollView.contentOffset = CGPointMake(0, 0);
newMiddleScrollView.contentOffset = CGPointMake(0, 0);
newTopScrollView.contentOffset = CGPointMake(320, 0);
UIScrollView *verticalScrollView_sub = (UIScrollView*)[self.view viewWithTag:VERTICAL_SUB];
[verticalScrollView_sub addSubview:newBottomScrollView];
[newBottomScrollView addSubview:newMiddleScrollView];
[newMiddleScrollView addSubview:newTopScrollView];
}
That's a good question - correct me if I'm wrong here, but it sounds that from left to right there's an arbitrary number of pages/cards, but only a few standard cards to come in from the top or bottom (your settings and details panels).
If that's the case, then you may well want to stick with something along the lines of a UIPageController alongside some gesture recognisers. You set up your page controller (or whatever controller you end up using to achieve your desired cards animation), and then add two gesture recognizers for swipe up and swipe down.
You can then animate your details/settings views in when you receive those gestures, giving you the card like interface without needing to bother with multiple UIPageViewControllers or a scroll view.
This approach isn't so great if you want an arbitrary number of cards in both the horizontal and vertical, but it sounds as if that's not the case.
There would be a lot of different ways to accomplish this, depending on how you want your different controllers to relate to each other. The slide transition itself is pretty simple. I've implemented it this way in a controller that's the superclass of the controller that calls the method:
-(void)SlideInController:(RDSlideController *) next {
next.presentingVC = self;
next.view.frame = CGRectMake(self.view.frame.origin.x + 320, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
[self.view.window addSubview:next.view];
[UIView animateWithDuration:1 animations:^{
next.view.frame = self.view.frame;
} completion:^(BOOL finished) {
self.view.window.rootViewController = next;
}];
}
Then from the newly presented controller, you can call this method to go back:
-(void)SlideOut {
UIViewController *prev = self.presentingVC;
prev.view.frame = self.view.frame;
[self.view.window insertSubview:prev.view belowSubview:self.view];
[UIView animateWithDuration:1 animations:^{
self.view.frame = CGRectMake(self.view.frame.origin.x + 320, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
} completion:^(BOOL finished) {
self.view.window.rootViewController = prev;
}];
}
I am implementing a sliding drawer on iOS5 (iPad). I have created the drawer by subclassing UIView. The drawer is added to the main view, which works fine. However, when I try to slide the drawer on/off screen using a swipe gesture and setFrame, the drawer does not move.
I believe I have implemented the gesture recognizer correctly, and the frame is also being set correctly. However, the drawer just does not move. Any thoughts on what I am doing wrong?
Below is my code:
The following method is called from viewDidLoad from my controller:
- (void)loadVerticalDrawer
{
NSLog(#"LoadVerticalDrawer Executed");
verticalDrawerHidden = YES;
if (verticalDrawerHidden) {
verticalDrawer = [[VerticalDrawer alloc] initWithFrame:CGRectMake(514, 250, 60, 248)];//adjust verticalDrawer height and width here;
} else {
verticalDrawer = [[VerticalDrawer alloc] initWithFrame:CGRectMake(464, 250, 60, 248)];//adjust verticalDrawer height and width here;
}
verticalDrawer.appsManager = appsManager;
verticalDrawer.delegate = self;
[self.view addSubview:verticalDrawer];
}
The following is also called from viewDidLoad:
rightDrawerLeftSwipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightDrawerHandleSwipeLeft:)] autorelease];
rightDrawerLeftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
rightDrawerLeftSwipe.numberOfTouchesRequired = 1;
rightDrawerLeftSwipe.delegate = self;
[verticalDrawer addGestureRecognizer:rightDrawerLeftSwipe];
rightDrawerRightSwipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(rightDrawerHandleSwipeRight:)] autorelease];
rightDrawerRightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
rightDrawerRightSwipe.numberOfTouchesRequired = 1;
rightDrawerRightSwipe.delegate = self;
[verticalDrawer addGestureRecognizer:rightDrawerRightSwipe];
FInally, this is the handler for the Right Swipe:
-(void) rightDrawerHandleSwipeRight:(UISwipeGestureRecognizer*) recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded)
{
if (!verticalDrawerHidden){
verticalDrawerHidden = YES;
float x = verticalDrawer.frame.origin.x;
float y = verticalDrawer.frame.origin.y;
float width = verticalDrawer.frame.size.width;
float height = verticalDrawer.frame.size.height;
NSLog(#"Swipe left, Vertical drawer, x=%f, y=%f, width=%f, height=%f:", x,y,width,height);
x+=50;
[verticalDrawer setFrame:CGRectMake(x,y,width,height)];
NSLog(#"Swipe left, Vertical drawer, x=%f, y=%f, width=%f, height=%f:", x,y,width,height);
return;
}
else {
return;
}
}
}
Please note that the frame of verticalDrawer is being set correctly (and the swipe handler is being called as desired), as per the logs, its just that the view is not moving at all!!