Problems implementing a container view - ios

I'm trying to follow the View Controller Programming Guide for iOS to implement a container view in my application. At the moment I'm just trying to get an initial first view to load but the label included in the first controller is not being shown. In the end, I hope to be able to control which view is shown in the container by using a segmented control.
Any help would be greatly appreciated.
My Storyboard
ViewController.h
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIView *contentController;
- (IBAction)SegmentedControlValueChange:(UISegmentedControl *)sender;
#end
ViewController.m
#import "ViewController.h"
#import "FirstController.h"
#import "SecondController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
FirstController *firstController = [[FirstController alloc] init];
[self displayContentController:firstController];
}
- (IBAction)SegmentedControlValueChange:(UISegmentedControl *)sender
{
}
- (void)displayContentController: (UIViewController *)content
{
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
}
- (CGRect)frameForContentController
{
return self.contentController.bounds;
}
#end

If FirstController is part of the storyboard, then you'll have to load it from the storyboard.
Try doing
FirstController *firstController = [self.storyboard instantiateViewControllerWithIdentifier:#"yourIdentifier"];

Related

How to use delegate between two ViewController without StoryBoard?

I'd like to trigger a message from viewController to another viewController.
And I coded like below, but viewController didn't call delegate.
I want to call delegate without stroyboard. I just want to send a message to another viewController.
viewController2.h
#protocol ViewController2Delegate;
#interface ViewController2 : UIViewController
#property (nonatomic, weak) id<ViewController2Delegate> delegate;
#end
#protocol ViewController2Delegate <NSObject>
- (void)showSomethingByDelegate;
#end
viewController2.m
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)buttonPressed:(id)sender {
[self.delegate showSomethingByDelegate];
}
#end
viewController.m
#import "ViewController.h"
#import "ViewController2.h"
#interface ViewController ()
<ViewController2Delegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ViewController2 *vc2 = [[ViewController2 alloc] init];
vc2.delegate = self;
}
// Below method was not called by delegate.
- (void)showSomethingByDelegate {
NSLog(#"Button Was Pressed!!!");
}
#end
well let me show an example more simple.
File: firstVC.h
/* This define the protocol object,
you can write methods required or optional the diference is when
the protocol is used in a class, xcode show you a yellow warning with required methods
like UITableViewDelegate, UITextFieldDelegate... */
#protocol firstVCDelegate <NSObject>
#required
- (void)didMessageFromOtherViewController: (NSString *)messageStr;
#optional
- (void)didOtherMessageNotRequired: (NSString *)messageStr;
#end
/* This is the definition of first UIViewController */
#interface firstViewController : UIViewController
#end
/* This is the definition of second UIViewController object with
a property that is our protocol 'firstVCDelegate' */
#interface secondViewController : UIViewController
#property (nonatomic, weak) id <firstVCDelegate> firstVCDelegate;
- (void)executeDelegateProcess;
#end
File: firstVC.m
#import "firstVC.h"
#pragma mark - First UIViewController with delegate
#interface firstViewController() <firstVCDelegate>
#end
#implementation firstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Creating the 'secondViewController' object with delegate on this class
secondViewController *svc = [secondViewController new];
// Assign the delegate class
[svc setFirstVCDelegate: self];
// Run the delegate logic
[svc executeDelegateProcess];
}
- (void)didMessageFromOtherViewController:(NSString *)messageStr
{
// Receiving the message from the instance of our protocol in the 'secondViewController' class
NSLog(#"MESSAGE #1: %#", messageStr);
}
- (void)didOtherMessageNotRequired:(NSString *)messageStr
{
// Receiving the message in optional method
NSLog(#"MESSAGE #2: %#", messageStr);
}
#end
#pragma mark - Second UIViewController
#implementation secondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)setFirstVCDelegate:(id<firstVCDelegate>)firstVCDelegate
{
if (firstVCDelegate)
_firstVCDelegate = firstVCDelegate;
}
- (void)executeDelegateProcess
{
// This method is only for demo
// You can execute your delegate in the way you need to use
if (_firstVCDelegate) {
[_firstVCDelegate didMessageFromOtherViewController: #"Hello world, using the required method from secondViewController class"];
[_firstVCDelegate didOtherMessageNotRequired: #"Hello code using the optional method"];
}
}
#end
In your appDelegate.m in the method didFinishLaunchingWithOptions you can put this, and you need to #import "firstVC.h"
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.autoresizesSubviews = YES;
[self.window makeKeyAndVisible];
[_window setRootViewController: [firstViewController new]];
Execute and see two logs messages, I hope I've helped :)
ViewController2 *vc2 = [[ViewController2 alloc] init];
This line of code is not doing what you think it is, this is creating a NEW instance of ViewController2 and storing it inside the variable vc2. At no point (based on your code) is this variable added to the navigation stack and displayed on screen.
Edit
Also as noticed by Holex, your vc2 variable will be removed from memory after the viewDidLoad is finished as you are not holding onto a reference of it. You would either need to create a property to hold onto it, or push it onto the navigation stack for the navigationController to hold onto it.
There are multiple ways to solve this issue:
Instead of creating a new viewController2, find a reference to the one already displayed on the screen (if it is on the screen).
If its not on the navigation stack, add vc2 to the navigation stack [self.navigationController pushViewController:vc2 animated:YES]; (assuming you have a navigation controller).
If not on the stack, and not intending to use a navigationController, present vc2 modally, such as [self presentViewController:vc2 animated:YES completion:nil];

how to dismiss view in MMTransitionAnimator

MMTransitionAnimator pod file was installed. View while swiping up and down its working fine but its not dismiss view while tap on button.Please refer this link github.com/mojun/MMTransitionAnimator.How to dismiss view while clicked on button action.can anyone help me.
While presenting:
self.modalVC.delegate = self;
In ModalViewController that is presented make a delegate that:
#protocol ModalViewControllerDelegate <NSObject>
#optional
- (void)closeButtonPressed;
#end
#interface ModalViewController : UIViewController
#property (nonatomic, weak) id <ModalViewControllerDelegate> delegate;
#end
#implementation ModalViewController
- (void)btnCloseTapped {
[self.delegate closeButtonPressed];
}
#end
Then Implement that delegate in your presenting view controller like:
- (void)closeButtonPressed {
//Needs to play more..
_animator = [[MMTransitionAnimator alloc] initWithOperationType:MMTransitionAnimatorOperationNone fromVC:_modalVC toVC:self];
_animator.usingSpringWithDamping = 0.8f;
_animator.interactiveType = MMTransitionAnimatorOperationDismiss;
_containerView.alpha = 1;
_handleBarView.y = self.view.height - _handleBarView.height;;
[self.modalVC dismissViewControllerAnimated:YES completion:nil];
}

Protocol/Delegate is not working

I have three UIViewcontroller, namely ViewController, BViewController and CViewController, ViewController is RootViewController from UINavigationController,
I'm pushing from ViewController -> BViewController -> CViewController, through button action.
I have declared protocol in CViewController. This protocol method is working fine for BViewController, but I don't understand how to make work its delegate method in ViewController.
I had created an object of CViewController in View Controller, then declared self for that delegate, though its not working, Below is my code. Please help me. Where I'm doing wrong here !
My Root View Controller, namely ViewController
#import "ViewController.h"
#import "BViewController.h"
#import "CViewController.h"
#interface ViewController ()<testDelegates>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:#"CViewController"];
cVC.mydelegate = self;
}
- (IBAction)nextAction:(id)sender {
BViewController *bViewC = [self.storyboard instantiateViewControllerWithIdentifier:#"BViewController"];
[self.navigationController pushViewController:bViewC animated:YES];
}
-(void)TestMethod{
NSLog(#" Its NOT Working");
}
My Second View Controller, Namely BViewController
#import "BViewController.h"
#import "CViewController.h"
#interface BViewController ()<testDelegates>
#end
#implementation BViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)bNextAction:(id)sender {
CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:#"CViewController"];
// cVC.mydelegate = self;
[self.navigationController pushViewController:cVC animated:YES];
}
-(void)TestMethod{
NSLog(#" Its Working If I uncomment to cVC.mydelegate = self");
}
And my third View Controller, Where i Declared a protocol in .h file, namely CViewController
#import <UIKit/UIKit.h>
#protocol testDelegates <NSObject>
-(void)TestMethod;
#end
#interface CViewController : UIViewController
#property (weak) id <testDelegates> mydelegate;
#end
And in .m file
#import "CViewController.h"
#interface CViewController ()
#end
#implementation CViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)cNextAction:(id)sender {
[self.mydelegate TestMethod];
}
You create class and this class destroying after you leave viewDidLoad method.
- (void)viewDidLoad {
[super viewDidLoad];
CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:#"CViewController"];
cVC.mydelegate = self;
}
As I understand you need to perform some methods in the ViewController from the CViewController.
You can pass viewController as delegate from the BViewController and them past it to the CViewController.
Or you can use code like this:
- (IBAction)cNextAction:(id)sender {
id< testDelegates > delegate = self.navigationController.viewControllers[0];
if([delegate conformsToProtocol:#protocol(testDelegates)])
{
[delegate TestMethod];
}
}
This is no best way but it's will be work.
Try this
self.delegate = self.navigationController.viewControllers[0];
You need to declare a another Protocol into BViewController class.
Please follow below steps.
Step 1: BViewController.h
#protocol testDelegates2 <NSObject>
-(void)TestMethod2;
#interface BViewController : UIViewController
#property (weak) id <testDelegates> mydelegate;
#end
#implementation CViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)cNextAction:(id)sender {
[self.mydelegate TestMethod2];
}
Step 2. In ViewController class conform Protocol
#interface ViewController ()<testDelegates>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:#"CViewController"];
cVC.mydelegate = self;
}
- (IBAction)nextAction:(id)sender {
BViewController *bViewC = [self.storyboard instantiateViewControllerWithIdentifier:#"BViewController"];
cVC.mydelegate = self; //important line
[self.navigationController pushViewController:bViewC animated:YES];
}
-(void)TestMethod2{
NSLog(#"Final Output");
}
If Your are trying to set Delegate of CViewController to ViewController then
try putting
self.mydelegate = self.navigationController.viewControllers[0]
on viewDidLoad method of CViewController.
Else you are Trying to make ViewController And BViewController both be Delegate of CViewController then this is not possible like this, as Delegate of a Object Can only be unique. This means the delegate is simply a variable which holds reference of object and as you know value to a variable can be unique at a instance of time.
So If you are willing to do some task on both Viewcontroller and BViewController then use notification pattern. See apple doc here

iOS How to control the UIContainer View show and disappear?

I had a UIViewController and a UIContainer View.
I want to simulate the UIAlertView effect, But I don't know how to build the Container View show and hide about the great method.
I had put the UITableView in my UIContainer View, I use delegate to send selected item to the UIViewController(ParentViewController) and show in the label.( segue name with alertSegue)
There have a show button in the ParentViewController,and I need click the selected item ,it will close(hide/dismiss?) the UIContainer View.
Now UIContainer View default is hidden,and storybaord screen shot like below:
My ParentViewController.h
#interface ViewController : UIViewController<ContainerViewBLETableDelegate>
#property (weak, nonatomic) IBOutlet UIButton *btn;
- (IBAction)btnAction:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *lb;
#property (weak, nonatomic) IBOutlet UIView *containerView;
-(IBAction)unwindSegue:(UIStoryboardSegue *)segue;
#end
.m file:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)btnAction:(id)sender {
_containerView.hidden = NO;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"alertSegue"])
{
ContainerViewBLETable *vc = segue.destinationViewController;
vc.delegate = self;
}
}
-(void) ContainerViewBLETable:(ContainerViewBLETable *)vc andSelectedDone:(NSString *)selectedStr
{
self.lb.text = selectedStr;
vc.view.hidden = YES;
}
-(IBAction)unwindSegue:(UIStoryboardSegue *)segue
{
}
Container ViewController .h :
#class ContainerViewBLETable;
#protocol ContainerViewBLETableDelegate <NSObject>
-(void) ContainerViewBLETable:(ContainerViewBLETable*)vc andSelectedDone:(NSString*)selectedStr;
#end
#interface ContainerViewBLETable : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property(nonatomic,assign) id<ContainerViewBLETableDelegate>delegate;
#property (weak, nonatomic) IBOutlet UITableView *tableVW;
#end
UIContainerView .m part:
.....
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate ContainerViewBLETable:self andSelectedDone:[NSString stringWithFormat:#"%ld",indexPath.row]];
}
.....
Although this code can pass the value to the UIViewController(ParentViewController),and the UIContainer View was hidden,but when I click the show button again , it was not any effect(I feel the container view was overlap lead to touch lose efficacy).
( by the way, I had try
[self.parentViewController dismissViewControllerAnimated:YES completion:nil];
it's not effect )
Question:
How to hide the container view use the delegate and that can touch the show button show container again?
And What great method to control the UIContainer view show and disappear in ParentViewController and UIContainerView ?
I really thank everyone and you can help me and better than better.
containerView and show button are in different viewControllers. So you can't just hide it. The simple way to achieve it is when you select the cell in containerView, present the ParentViewController, and the view in ContainerViewController will dismiss automatically.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate ContainerViewBLETable:self andSelectedDone:[NSString stringWithFormat:#"%ld",indexPath.row]];
ParentViewController *vc = [[self storyboard] instantiateViewControllerWithIdentifier:#"ParentViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
To show the container, you can just dismiss the ParentViewController that presenting.
1.
- (IBAction)btnAction:(id)sender
{
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
Or
2. Set up segue to dismiss viewController and use prepareForSegue for delegate to communicate with other viewController.
Also REMOVE vc.view.hidden = YES in delegate you had implemented
-(void) ContainerViewBLETable:(ContainerViewBLETable *)vc andSelectedDone:(NSString *)selectedStr.

Add a CollectionViewController as ChildViewController to a UIView

I am trying to create a view which contains three subview having different view controller (UICollectionViewController,pageviewcontroller and uiviewcontroller).
i am able to add a uiviewcontroller but other two controller is not allowed.
I am getting this error.....
Incompatible pointer types sending 'UICollectionView *__weak' to parameter of type 'UIViewController *'
Is their any way to add these controller to my subview?
I don't know why you want to add ViewControllers inside a view, i never need it.
I tried to do that, if can help you this is my running code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, retain) UICollectionViewController *collectionViewController;
#property (nonatomic, retain) UIPageViewController *pageViewController;
#property (nonatomic, retain) UIViewController *simpleViewController;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize collectionViewController;
#synthesize pageViewController;
#synthesize simpleViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
collectionViewController = [[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
pageViewController = [[UIPageViewController alloc] init];
simpleViewController = [[UIViewController alloc] init];
// Do your stuff with this controllers
[self.view addSubview:collectionViewController.view];
[self.view addSubview:pageViewController.view];
[self.view addSubview:simpleViewController.view];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You don't add view controllers to views. You add views to views (as subviews) and, much more rarely, controllers to controllers (as child controllers).
Think of them as two parallel hierarchies: Given ControllerA that controls view ViewA, you want to make ControllerB a child controller of ControllerA such that it's view, ViewB is a subview of ViewA.
See the WWDC 2011 video: "Implementing UIViewController Containment"

Resources