Подкласс UIButton, но не могу получить доступ к моим свойствам - PullRequest
0 голосов
/ 27 мая 2010

Я создал подкласс UIButton:

//
//  DetailButton.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MyDetailButton : UIButton {
    NSObject *annotation;
}

@property (nonatomic, retain) NSObject *annotation;


@end

//
//  DetailButton.m
//


#import "MyDetailButton.h"


@implementation MyDetailButton


@synthesize annotation;

@end

Я решил, что смогу создать этот объект и установить объект аннотации, выполнив следующие действия:

MyDetailButton* rightButton = [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure];
rightButton.annotation = localAnnotation;

localAnnotation - это NSObject, но на самом деле это MKAnnotation. Я не могу понять, почему это не работает, но во время выполнения я получаю эту ошибку:

 2010-05-27 10:37:29.214 DonorMapProto1[5241:207] *** -[UIButton annotation]: unrecognized selector sent to instance 0x445a190
2010-05-27 10:37:29.215 DonorMapProto1[5241:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIButton annotation]: unrecognized selector sent to instance 0x445a190'

Я не могу понять, почему он даже смотрит на UIButton, потому что я подклассифицировал это, поэтому он должен смотреть на класс MyDetailButton, чтобы установить это свойство аннотации. Я пропустил что-то действительно очевидное. По ощущениям:)

Заранее благодарим за любую помощь, которую вы можете оказать

Ross

Ответы [ 4 ]

14 голосов
/ 13 июня 2010

UIButton - это кластер классов, из которого следует, что реализация Apple buttonWithType:, вероятно, выглядит примерно так:

+(id)buttonWithType:(UIButtonType)t {
  switch (t) {
    case UIButtonTypeDetailDisclosure:
      return [[[PrivateDetailDisclosureButtonClass alloc] init] autorelease];
    case ...
  }
}

Так что, когда вы звоните [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure];, вы не получаете экземпляр MyDetailButton, вы получаете экземпляр PrivateDetailDisclosureButtonClass (или как Apple его называет).

Обратите внимание, однако, что вы можете получить buttonWithType для создания экземпляра подкласса, если вы вызовете его с помощью UIButtonTypeCustom (по крайней мере, в симуляторе с версией 3.0):

// LGButton is a straightforward subclass of UIButton
LGButton *testBtn = [LGButton buttonWithType:UIButtonTypeCustom];
LGButton *testBtn2 = [LGButton buttonWithType:UIButtonTypeDetailDisclosure];
NSLog(@"testBtn: %@, testBtn2: %@", [testBtn class], [testBtn2 class]);
// Output: testBtn: LGButton, testBtn2: UIButton
2 голосов
/ 05 октября 2011

Я предпринял ту же попытку, что и оригинальный постер, но кажется, что создать подкласс UIButton что-то вроде этого сложно.

То, что я сделал, это взлом, но теперь он работает для меня, это добавление UITextField как подпредставления UIButton. UITextField не имеет рамки и скрыт, но я могу свободно хранить текстовые строки в текстовом свойстве текстового поля. Что я и хотел сделать ...

UITextField* tf = [[UITextField alloc] init];
tf.text = @"the text that I wanna store";
tf.hidden = YES;
tf.tag = TAGOFBUTTONSUBTEXTFIELD;
[previouslyCreatedButton addSubview:tf];
[tf release];

Я где-то определил TAGOFBUTTONSUBTEXTFIELD как 99. Глобальный. Это некрасиво, но ...

Затем, чтобы получить эту текстовую строку, используйте что-то вроде этого:

+(NSString*)getStoredStringFromButton:(UIButton*)button {
    UITextField* tf = (UITextField*)[button viewWithTag:TAGOFBUTTONSUBTEXTFIELD];
    return tf.text;
}

Таким образом, предполагается, что никто другой не пытается добавить к кнопке подпредставление с тегом 99.

Lol: -)

1 голос
/ 27 мая 2010

Это исключение, потому что фактическая кнопка, от которой вы пытаетесь получить аннотацию, , а не класса MyDetailButton, это UIButton. Убедитесь, что вы установили класс в IB для этой конкретной кнопки. Выберите кнопку в IB и нажмите ⌘4, чтобы увидеть ее идентификатор, измените идентификатор класса на MyDetailButton.

0 голосов
/ 27 мая 2010

Просто создать подкласс недостаточно; подкласс не заменяет своего суперкласса. Таким же образом не все UIControls, не все UIViews, не все UIResponders и не все NSObjects имеют поведение UIButton, не все UIButton имеют поведение вашего пользовательского подкласса.

То, что вам нужно, это экземпляр вашего подкласса. То, что у вас есть, является экземпляром UIButton.

Решение состоит в том, чтобы сделать этот экземпляр экземпляром вашего подкласса. Если вы создали кнопку в Интерфейсном Разработчике, выберите кнопку и нажмите ⌘6, затем измените там Таможенный класс экземпляра. Если вы создаете кнопку в коде, отправьте ваше сообщение alloc в ваш пользовательский подкласс, а не напрямую в UIButton.

...