t1w
t1w

Reputation: 1428

Delegate doesn't work when trying to segue from UIView's button to another ViewController

I'm trying to programmatically segue to a view controller which is on another storyboard.

To give more details; I've an UILabel and UIButton on my xib where UILabel contains a "Lorem ipsum" and button's type changed custom so that it can be transparent. I've set the button's size to cover all xib file. So when user tap on button, i can create a segue within that button's action.

I know i can't do this directly, so i must have a delegate method which will be invoked from my xib's parent viewcontroller. When i run my project, it keeps falling into else block of Mini.m file's btnClick action.

enter image description here

I've also done some searching and read some previous posts on SO like following links but somehow couldn't manage to solve the issue. Any ideas what am i missing here?

https://stackoverflow.com/a/35583877/1450201

https://stackoverflow.com/a/6169104/1450201

https://stackoverflow.com/a/30508168/1450201

https://stackoverflow.com/a/10520042/1450201

Mini.h

#import <UIKit/UIKit.h>

@protocol SelectionProtocol;

@interface Mini : UIView

@property (nonatomic, weak) id<SelectionProtocol> delegate;

- (IBAction)btnClick:(id)sender;

@end


@protocol SelectionProtocol <NSObject>

@required
-(void) isClicked;

@end

Mini.m

#import "Mini.h"

@implementation Mini

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self load];
    }

    return self;
}


- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self load];
    }
    return self;
}

- (void)load {
    UIView *view = [[[NSBundle bundleForClass:[self class]] loadNibNamed:@"Mini" owner:self options:nil] firstObject];
    [self addSubview:view];
    view.frame = self.bounds;

    //    ui component properties will be set here

}
- (IBAction)btnClick:(id)sender {

    if (self.delegate && [self.delegate respondsToSelector:@selector(isClicked)]) {
        [self.delegate isClicked];
    } else {
        NSLog(@"AAAAAAAAAAAAAA");
    }
}

@end

ViewController.h

#import <UIKit/UIKit.h>
#import "Mini.h"

@interface ViewController : UIViewController <SelectionProtocol>

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


-(void) isClicked {
    UIStoryboard *targetStoryBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *targetVC = (UIViewController *)[targetStoryBoard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    [self.navigationController pushViewController:targetVC animated:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Edit: I'm using my UIView as a subview of my UIViewCotnroller. Here's a scfeenshot enter image description here


Edit 2: Screenshots for my latest changes: (Still can't navigate to SecondViewController) enter image description here

enter image description here

enter image description here

Upvotes: 0

Views: 137

Answers (3)

iticle
iticle

Reputation: 131

You should specify a instance who conform to the protocol as the delegate.object.delegate = self.

Upvotes: 0

Adeel Miraj
Adeel Miraj

Reputation: 2496

You are not setting the ViewController as the delegate of Mini view. I assume that the Mini view is a subview of ViewController. All you need to do is create a reference/pointer of this view in the ViewController class and set it as the delegate of the View.

  1. Create an outlet of your view and connect it with the view placed in the storyboard. Don't forget to change the class of this view to Mini in the identity inspector of the Xcode

    #import "Mini.h"
    
    @interface ViewController : UIViewController <SelectionProtocol>
        @property (weak, nonatomic) IBOutlet Mini *miniView;
    @end
    
  2. In the viewDidLoad set the delegate of this view

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.miniView.delegate = self;
    }
    

Upvotes: 1

vikram
vikram

Reputation: 181

Just set delegate like this

In ViewController.m

- (void)viewDidLoad {

[super viewDidLoad];

Mini *view = [[Mini alloc]init];
 view.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}

Upvotes: 1

Related Questions