SWRevealViewController : Make Starting Background View Grey with custom animations - ios

I am fairly new to iOS. I tried to look this up but couldn't find a definite answer to the following.
I have a SWRevealViewController to handle side menu bar from my FirstPage.
When the SWReveal appears after clicking btn_Menu (or by swiping left) I want the FirstPage to become grey and unusable.
I see that in FirstPage we have to do the following:
[btn_Menu addTarget:self.revealViewController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
I need to change the revealToggle method somehow, or write a new selector in FirstPage which darkens it first, and then calls revealToggle ? I am unsure what's the best and easiest way to get this done. Thanks a lot.

In your FirstPage viewDidLoad do this code.
- (void)viewDidLoad
{
SWRevealViewController * revealController=[[SWRevealViewController alloc]init];
revealController = [self revealViewController];
[self.view addGestureRecognizer:revealController.panGestureRecognizer];
revealController.delegate=self;
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
[btnSideMenu addTarget:revealController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
}
After that add this delegate method of SWRevealViewController in to your FirstPage.
- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position
{
if (revealController.frontViewPosition == FrontViewPositionRight)
{
UIView *lockingView = [UIView new];
lockingView.translatesAutoresizingMaskIntoConstraints = NO;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:revealController action:#selector(revealToggle:)];
[lockingView addGestureRecognizer:tap];
[lockingView addGestureRecognizer:revealController.panGestureRecognizer];
[lockingView setTag:1000];
[revealController.frontViewController.view addSubview:lockingView];
lockingView.backgroundColor=[UIColor grayColor];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(lockingView);
[revealController.frontViewController.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"|[lockingView]|"
options:0
metrics:nil
views:viewsDictionary]];
[revealController.frontViewController.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[lockingView]|"
options:0
metrics:nil
views:viewsDictionary]];
[lockingView sizeToFit];
}
else
[[revealController.frontViewController.view viewWithTag:1000] removeFromSuperview];
}

Related

Adding a ChildViewController causes strange behavior to the child viewcontroller

By "strange", I am noticing the following behavior:
background color set by the ChildViewController does not appear
despite adding a basic tap gesture recognizer to the ChildViewController, there is no tap recognition
adding a UIButton to the ChildViewController results in the UIButton shown, but there is no response when tapping on the UIButton part
In my ParentViewController, I present the ChildViewController very generically, like so:
UIViewController *viewController;
viewController = (ChildViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"ChildViewController"];
[self addChildViewController:viewController];
viewController.view.frame = self.view.bounds;
viewController.view.translatesAutoresizingMaskIntoConstraints = NO;
viewController.view.center = self.view.center;
[self.view addSubview:viewController.view];
[self.view bringSubviewToFront:viewController.view];
[viewController didMoveToParentViewController:self];
And here are some very basic things I do in ChildViewController's viewDidLoad:
self.view.backgroundColor = [UIColor yellowColor];
UIButton *tapButton = [UIButton buttonWithType:UIButtonTypeSystem];
[tapButton addTarget:self action:#selector(tappedOnTap) forControlEvents:UIControlEventTouchUpInside];
//button view customization code omitted for brevity
tapButton.userInteractionEnabled = YES;
tapButton.enabled = YES;
[self.view addSubview:tapButton];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tappedOnView)];
[self.view addGestureRecognizer:tapGesture];
[self.view setUserInteractionEnabled:YES];
[self.view addGestureRecognizer:tapGesture];
I ensured that everything is hooked up correctly - however, there is no acknowledgment in tappedOnView and tappedOnTap when I tap on it, in both simulator or device.
Am I missing something basic about presenting a ChildViewController?
Edit
For those curious, this very basic app is on Github.
The containment calls are fine. But if you use the view debugger (), you'll see the frame is not correct. This is because you've turned off translatesAutoresizingMaskIntoConstraints, but you don't have any constraints. You can either turn that back on (and set autoresizingMask accordingly):
viewController.view.translatesAutoresizingMaskIntoConstraints = true;
Or you can define constraints rather than setting the frame (and redundantly setting the center):
//viewController.view.frame = self.view.bounds;
viewController.view.translatesAutoresizingMaskIntoConstraints = false;
//viewController.view.center = self.view.center;
[self.view addSubview:viewController.view];
[NSLayoutConstraint activateConstraints:#[
[viewController.view.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[viewController.view.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
[viewController.view.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[viewController.view.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
]];
Try this:
ChildViewController *viewController;
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ChildViewController"];
viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleheight;
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
Usually you don't need to do anything when adding a ViewController to another except those basic methods. since the views will be adjusted automatically and you don't need to set all those properties like size and center etc...

Container view change view dynamically

I have the following layout.
Green and Orange views are extra views added to the view controller.
I want to change the contained view controllers view to be changed according to the button user clicked.
I have Answer Using UIContainer dynamically show two ViewControllers in ios,
I have Create BaseViewController and Two viewControllers(GreenViewController and OrangeViewController), let seen below image are
And baseView inserted two UIButton(Green and Orange button), UIContainerView and the source is below,
BaseViewController.h file:
#property (weak, nonatomic) IBOutlet UIView *containView;
#property (weak, nonatomic) UIViewController *currentViewController;
BaseViewController.m file:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_currentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"GreenViewController"];
_currentViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[self addChildViewController:_currentViewController];
[self addSubview:_currentViewController.view toView:_containView];
}
- (void)addSubview:(UIView *)subView toView:(UIView*)parentView {
[parentView addSubview:subView];
NSDictionary * views = #{#"subView" : subView,};
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[subView]|"
options:0
metrics:0
views:views];
[parentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[subView]|"
options:0
metrics:0
views:views];
[parentView addConstraints:constraints];
}
- (void)cycleFromViewController:(UIViewController*) oldViewController
toViewController:(UIViewController*) newViewController {
[oldViewController willMoveToParentViewController:nil];
[self addChildViewController:newViewController];
[self addSubview:newViewController.view toView:self.containView];
[newViewController.view layoutIfNeeded];
// set starting state of the transition
newViewController.view.alpha = 0;
[UIView animateWithDuration:0.5
animations:^{
newViewController.view.alpha = 1;
oldViewController.view.alpha = 0;
}
completion:^(BOOL finished) {
[oldViewController.view removeFromSuperview];
[oldViewController removeFromParentViewController];
[newViewController didMoveToParentViewController:self];
}];
}
Green Button Action is below
- (IBAction)greenViewAction:(id)sender {
UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"GreenViewController"];
newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[self cycleFromViewController:self.currentViewController toViewController:newViewController];
self.currentViewController = newViewController;
}
Orange Button Action is below
- (IBAction)orangeViewAction:(id)sender {
UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"OrangeViewController"];
newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[self cycleFromViewController:self.currentViewController toViewController:newViewController];
self.currentViewController = newViewController;
}
its working for me, see the output below,
hope its helpful

iOS:Help Blur screen on the top of home view

my application needs help sceen on top of the home view controller.I have taken the tabbar controller as a root view controller and added navigation view controller .So in appearance of the first screen both tabbar and navigation bar appears along with view body.When i tried to place the help screens by pageviewcontroller examples at the time of view did load in the first screen tab view and navigation bar are coming front keeping the page view controller back .i have tried
[self addChildViewController:walkthrough];
[self.view addSubview:walkthrough.view];
[self.tabBarController.view bringSubviewToFront:walkthrough.view];
please help how to get the page view screen front.And is there any examples tutorial please help me
Note:Botn navigation bar and tabbar should not be hide
This is what I have done for walkthrough in my application. You can download this FXBlurView library from here:
https://github.com/nicklockwood/FXBlurView
In my .h file
#import "FXBlurView.h"
IBOutlet UIView *viewWalkThrough;
FXBlurView *overlayView;
In my .m file
#define SYSTEM_SCREEN_SIZE [[UIScreen mainScreen] bounds].size
#define kProfileWalkthrough #"ProfileWalkthrough"
if (![[[NSUserDefaults standardUserDefaults] valueForKey:kProfileWalkthrough] boolValue]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kProfileWalkthrough];
[[NSUserDefaults standardUserDefaults] synchronize];
overlayView = [[FXBlurView alloc] initWithFrame:CGRectMake(0, 0, SYSTEM_SCREEN_SIZE.width, SYSTEM_SCREEN_SIZE.height)];
[overlayView setDynamic:YES];
[overlayView setBlurRadius:5.0f];
[overlayView setBlurEnabled:YES];
[overlayView setTintColor:[UIColor blackColor]];
[self.view.window addSubview:overlayView];
[self displayOverlay:viewWalkThrough aboveView:self.view.window];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(closeWalkThrough:)];
[viewWalkThrough addGestureRecognizer:tapGesture];
}
- (void)closeWalkThrough:(UITapGestureRecognizer *)tapRecognizer {
[overlayView removeFromSuperview];
[self.viewWalkThrough removeFromSuperview];
}
- (void)displayOverlay:(UIView *)subView aboveView:(UIView *)superView {
subView.translatesAutoresizingMaskIntoConstraints = NO;
[superView addSubview:subView];
[superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[subView]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(subView)]];
[superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[subView]|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(subView)]];
[superView layoutSubviews];
}

iOS 7.1 UITableView layoutSubviews issue

I'm working on a project that must support both iOS 8 and iOS 7.1. Right now I'm running into a problem that only appears on iOS 7.1 but works properly on iOS 8. I have a ViewController that contains a tableview and a custom view in the tableHeaderView. I'll post the code as follows. All constraints are added programatically.
//View Controller.
-(void)viewDidLoad
{
[super viewDidLoad];
self.commentsArray = [NSMutableArray new];
[self.commentsArray addObject:#"TEST"];
[self.commentsArray addObject:#"TEST"];
[self.commentsArray addObject:#"TEST"];
[self.commentsArray addObject:#"TEST"];
[self.commentsArray addObject:#"TEST"];
[self.commentsArray addObject:#"TEST"];
[self.view addSubview:self.masterTableView];
self.masterTableView.tableHeaderView = self.detailsView;
[self.view setNeedsUpdateConstraints];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view layoutIfNeeded];
}
//Table view getter
- (UITableView *)masterTableView
{
if(!_masterTableView)
{
_masterTableView = [UITableView new];
_masterTableView.translatesAutoresizingMaskIntoConstraints = NO;
_masterTableView.backgroundColor = [UIColor greyColor];
_masterTableView.delegate = self;
_masterTableView.dataSource = self;
_masterTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_masterTableView.showsVerticalScrollIndicator = NO;
_masterTableView.separatorInset = UIEdgeInsetsZero;
}
return _masterTableView;
}
-(void)updateViewConstraints
{
NSDictionary *views = #{
#"table" : self.masterTableView,
#"details" : self.detailsView,
};
NSDictionary *metrics = #{
#"width" : #([UIScreen mainScreen].applicationFrame.size.width)
};
//Table view constraints
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[table]-0-|" options:0 metrics:0 views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[table]-0-|" options:0 metrics:0 views:views]];
//Details View
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[details(width)]-0-|" options:0 metrics:metrics views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[details]-0-|" options:0 metrics:metrics views:views]];
}
//Details View Getter
- (DetailsView *)detailsView
{
if(!_detailsView)
{
_detailsView = [[DetailsView alloc]initWithFrame:CGRectMake(0, 0, 0, 100)];
_detailsView.backgroundColor = [UIColor orangeColor];
return _detailsView;
}
Now the details view contains some basic subviews which all derive from a UIView and the details view itself derives from a more general super class. I'll post the code as follows.
//Parent View
#interface ParentView (): UIView
- (instancetype)init
{
self = [super init];
if (self)
{
[self setupViews];
}
return self;
}
- (void)setupViews
{
[self addSubview:self.publishedTimeView];
}
- (void)updateConstraints
{
NSDictionary *views = #{
#"time" : self.publishedTimeView,
};
// Header with published video time
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[time]-10-|" options:0 metrics:0 views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[time(11)]" options:0 metrics:0 views:views]];
[super updateConstraints];
}
//Getter for the timePublished view added to the detail view. Will not post all its related code for //the sake of brevity.
- (TimePublishedDetailView *)publishedTimeView
{
if(!_publishedTimeView)
{
_publishedTimeView = [TimePublishedDetailView new];
_publishedTimeView.translatesAutoresizingMaskIntoConstraints = NO;
}
return _publishedTimeView;
}
//Child View (or the detailsView) of the view controller.
#interface DetailsView : ParentView
#implementation RecordingDetailsView
- (void)updateConstraints
{
NSDictionary *views = #{
#"time" : self.publishedTimeView,
};
//Vertical alignment of all views
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[time]" options:0 metrics:nil views:views]];
[super updateConstraints];
}
- (void)setModel:(DetailViewModel *)model
{
self.publishedTimeView.date = model.dateTime;
[self setNeedsUpdateConstraints];
[self layoutSubviews];
}
Now on iOS 8 this looks like this:
However on iOS 7.1 this will crash with this error message:
"Exception: Auto layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super"
I've googled this and played around with the code in my layout calls to see if I can remedy the problem but so far have been unsuccessful. If anyone could post some tips or advice on how to fix this I would really appreciate it.
I know this question is old, but I ran into a similar problem recently and after a lot of Googling, trying and failing I made it work with the help of this answer and a few changes.
Just add this category to your project and call [UITableView fixLayoutSubviewsMethod]; only once (I recommend inside AppDelegate).
#import <objc/runtime.h>
#import <objc/message.h>
#implementation UITableView (FixUITableViewAutolayoutIHope)
+ (void)fixLayoutSubviewsMethod
{
Method existing = class_getInstanceMethod(self, #selector(layoutSubviews));
Method new = class_getInstanceMethod(self, #selector(_autolayout_replacementLayoutSubviews));
method_exchangeImplementations(existing, new);
}
- (void)_autolayout_replacementLayoutSubviews
{
[super layoutSubviews];
[self _autolayout_replacementLayoutSubviews]; // not recursive due to method swizzling
[super layoutSubviews];
}
#end

Forcing a subview background color change when rotating device and autolayout

I have a problem with a custom view and autolayout. To make things simple I will use two UILabels, the first one should change its background color when the device rotate. The problem is that it doesn't do it! Any hint?
Thanks!
Nicola
- (id)init
{
self = [super init];
if (self) {
//Add the subviews to the mainView
[self.view addSubview:self.label1];
[self.view addSubview:self.label2];
//Autolayout
//Create the views dictionary
NSDictionary *viewsDictionary = #{#"header":self.label1,
#"table": self.label2};
//Create the constraints using the visual language format
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[header]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[table]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[header(==50)][table]|"
options:0
metrics:nil
views:viewsDictionary]];
}
return self;
}
-(UIView*) label1
{
_label1 = [UILabel alloc] init];
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
_label1.backgroundColor = [UIColor redColor];
}else{
_label1.backgroundColor = [UIColor greenColor];
}
_label1.translatesAutoresizingMaskIntoConstraints=NO;
return _label1;
}
-(UIView*) label2
{
_label2 = [UILabel alloc] init];
_label2.backgroundColor = [UIColor yellowColor];
_label2.translatesAutoresizingMaskIntoConstraints=NO;
_return label2;
}
-(BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger) supportedInterfaceOrientations
{
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){
//I am on a pad
return UIInterfaceOrientationMaskAll;
} else {
//I am on a Phone
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//I expect the label1 to change its background color
[self.view setNeedDisplay];
}
If you move the code related to [self.label1 setBackgroundColor:] to the delegate method didRotateFromInterfaceOrientation:, it should work better. Also, in your custom getters, you are allocating a new label every time you access the method. In most situations it's preferable to check if the ivar is not nil at the beginning, and returning the ivar, instead for allocating a fresh label.

Resources