协议不起作用

时间:2015-09-07 16:12:47

标签: ios objective-c

您好我在导航栏上以编程方式添加了一个自定义按钮,我在后台课程中编写了所有按钮属性,我从我的主课程中调用此方法

在这里,我已经使用协议从后台课程中获取主要课程中的按钮触摸事件但是它没有使用协议

我的代码: -

后台课程: -

BackGroundClass.h

#import <UIKit/UIKit.h>

@protocol buttonprotocol<NSObject>
@required
- (void) buttonTapped;
@end

@interface BackGroundClass : UIViewController

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

@end

BackGroundClass.m

#import&#34; BackGroundClass.h&#34;

@interface BackGroundClass ()

@end

@implementation BackGroundClass
@synthesize delegate;

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

- (void)backbutton: (UINavigationItem *)navigationitem
{
        UIImage* image3 = [UIImage imageNamed:@"back.png"];
        CGRect frameimg = CGRectMake(15,5,25,25);

        UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
        [someButton setBackgroundImage:image3 forState:UIControlStateNormal];
        [someButton addTarget:self action:@selector(Back_btn:)
             forControlEvents:UIControlEventTouchUpInside];
        [someButton setShowsTouchWhenHighlighted:YES];

        UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
        navigationitem.leftBarButtonItem = mailbutton;
}

- (void)Back_btn :(id)sender
{
   [delegate buttonTapped];
}

@end

主要班级: -

mainclass.h

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

@interface mainclass : UIViewController<buttonprotocol>

mainclass.m

#import "mainclass.h"
#import "BackGroundClass.h"

@interface mainclass ()
{
 BackGroundClass * bg;
}

@end

@implementation mainclass

- (void)viewDidLoad {
    [super viewDidLoad];

    bg = [[BackGroundClass alloc]init];
    [bg backbutton:self.navigationItem];
}

- (void)buttonTapped
{
    NSLog(@"ok it's 2");
}

但是上面的按钮点击了一个方法并没有被称为我做错了什么?

2 个答案:

答案 0 :(得分:1)

当你创建BackGroundClass类的对象时,你没有将类的委托设置为self,这就是你的委托方法没有调用的原因,请尝试这样做

bg = [[BackGroundClass alloc]init];
bg.delegate = self;

答案 1 :(得分:1)

首先,在类名中使用 Class 是不好的做法。对于视图控制器,您应该使用ViewController或VC postfix作为类名。

例如,Objective-C类的专有名称是: BackgroundViewController,MainViewController

其次,ViewController实例用于响应用户与附加到此ViewController的视图的交互,并基于 MVC 工作的数据组件提供可见更改。 因此,没有理由使用第二个,在您的情况下 BackgroundViewController(BackgroundClass)

有关MVC模式的更多信息,请参阅此链接: Apple's MVC articles

由于在外部ViewController中没有必要,我们也应该删除委托,并将所有逻辑放在这个主视图控制器中。

第三,如Apple's Mobile HIG中所述,按钮的高度应为44px左右,因此后退按钮的大小为25x25会使大多数用户在尝试点击它时遇到困难。

最后,您应该收到类似于它的类:

<强> MainViewController.h

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController


@end

<强> MainViewController.m

#import "MainViewController.h"

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *icon = [UIImage imageNamed:@"back.png"];

    static CGFloat defaultButtonSize = 44.; // Default button's tap area size

    CGSize buttonSize = CGSizeMake(defaultButtonSize, defaultButtonSize);
    // The size image should take inside the button
    CGSize imageSizeInsideButton = CGSizeMake(25., 25.); 

    CGRect frameimg = CGRectMake(15., 5., defaultButtonSize, defaultButtonSize);

    UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
    [someButton setImage:icon forState:UIControlStateNormal];
    [someButton addTarget:self
                   // No need to put colon after method name,
                   // since you have no use of control that triggered action
                   action:@selector(backButtonClicked)                                      
         forControlEvents:UIControlEventTouchUpInside];

    someButton.showsTouchWhenHighlighted = YES;

    // Calculate edge insets so image will take the size 
    // you specified dozen of lines before
    CGFloat imageVerticalPaddingInButton = (buttonSize.height - imageSizeInsideButton.height) / 2.;
    CGFloat imageHorizontalPaddingInButton = (buttonSize.height - imageSizeInsideButton.height) / 2.;

    // Apply it to button
    someButton.imageEdgeInsets = UIEdgeInsetsMake(imageVerticalPaddingInButton,
             imageHorizontalPaddingInButton, 
             imageVerticalPaddingInButton, 
             imageHorizontalPaddingInButton);

    UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
    self.navigationItem.leftBarButtonItem = mailbutton;
}

// As stated in "addTarget", there is no "sender" since you don't really need it
// If you ever would need the use of it, 
// don't forget to put colon in "addTarget" UIButton's method
// and place something like :(UIButton *)buttonThatClicked
// after methodName
- (void)backButtonClicked {
    // Get back to your previous view controller or do whatever you like there
    [self.navigationController popViewControllerAnimated:YES];
}

@end

但是如果你想在尽可能多的View Controllers中使用这个东西,那么你应该创建类别:

<强>的UIViewController + CustomBackButton.h

#import <UIKit/UIKit.h>

@interface UIViewController (CustomBackButton)

- (void)setBackButtonImage:(UIImage *)image withSize:(CGSize)size target:(id)target selector:(SEL)selector;

@end

<强>的UIViewController + CustomBackButton.m

#import "UIViewController+CustomBackButton.h"

@implementation UIViewController (CustomBackButton)

- (void)setBackButtonImage:(UIImage *)image withSize:(CGSize)size target:(id)target selector:(SEL)selector {
    static CGFloat defaultButtonSize = 44.;

    CGSize buttonSize = CGSizeMake(defaultButtonSize, defaultButtonSize);

    CGRect frameimg = CGRectMake(15., 5., defaultButtonSize, defaultButtonSize);

    UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
    [someButton setImage:image forState:UIControlStateNormal];
    [someButton addTarget:target
                   action:selector
         forControlEvents:UIControlEventTouchUpInside];

    someButton.showsTouchWhenHighlighted = YES;

    CGFloat imageVerticalPaddingInButton = (buttonSize.height - size.height) / 2.;
    CGFloat imageHorizontalPaddingInButton = (buttonSize.height - size.height) / 2.;

    someButton.imageEdgeInsets = UIEdgeInsetsMake(imageVerticalPaddingInButton,
                                                  imageHorizontalPaddingInButton,
                                                  imageVerticalPaddingInButton,
                                                  imageHorizontalPaddingInButton);

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:someButton];
    self.navigationItem.leftBarButtonItem = backButton;
}

@end

然后你的View Controller的实现文件会更清晰。

<强> MainViewController.m

#import "MainViewController.h"
#import "UIViewController+CustomBackButton.h"

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIImage *icon = [UIImage imageNamed:@"back.png"];
    CGSize iconSize = CGSizeMake(25., 25.);

    [self setBackButtonImage:icon
                    withSize:iconSize
                      target:self
                    selector:@selector(backButtonClicked)];
}

- (void)backButtonClicked {
    // Get back to your previous view controller or do whatever you like there
    [self.navigationController popViewControllerAnimated:YES];
}

@end

然后你可以在每个ViewController上使用它来自定义你的后退按钮。