在Objective-C,iOS中突出显示另一个类的按钮

Posted

技术标签:

【中文标题】在Objective-C,iOS中突出显示另一个类的按钮【英文标题】:Highlighting a button from another class in objective-C, iOS 【发布时间】:2016-03-08 15:17:48 【问题描述】:

我有一个应用程序,其中包含用于处理 BT 连接的蓝牙 LE 类。当一个特征值改变时,我希望 BT 类中的代码改变主视图控制器上的按钮状态。我是 obj-c 的新手,通常使用 *** 来帮助我理解。我在视图控制器中定义了以下内容:

@interface myViewController : UIViewController<CLLocationManagerDelegate, UITableViewDataSource, UITableViewDelegate, UINavigationBarDelegate, UIActionSheetDelegate>


@property (weak, nonatomic) IBOutlet UIButton *eraseButton;

在视图控制器中,我可以愉快地改变按钮状态:

[self.eraseButton setHidden:YES];

-(void) deselectEraseButton

    [self.eraseButton setSelected:NO];

在 BT 类中,我尝试了很多事情(更改 viewcontroller 的属性,该属性通过计时器更改按钮状态,调用直接更改按钮状态的方法等)并且虽然执行了代码(我设置了断点myViewController 中的代码),按钮状态没有改变。例如:

myAppDelegate *app = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
            app.vCtrl=[[myViewController alloc] init];
            [app.vCtrl deselectEraseButton];

我做错了什么,最好的方法是什么?我相信它不应该这么难!

更新:

在蔡志伟的帮助下(谢谢),我做了一些改变,但是还是不行:

我在 myAppDelegate.h 中添加了以下内容:

@property (strong, nonatomic) myViewController* vCtrl;

我在 myAppDelegate.m 中添加了以下内容:

-(void)eraseButton:(BOOL)state
    [vCtrl accessEraseButton:state];

在 BT 课程中,我执行以下操作:

[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];

在该类中使用以下方法:

-(void) test
    
        myAppDelegate *app = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
        [app eraseButton:0];

这称为 myViewController 并在 thread1 上执行以下操作:

-(void) accessEraseButton: (BOOL) state

    if (state==0)
    
        [self.eraseButton setSelected:NO];
        [self.view setNeedsDisplay];
    
    else
    
        [self.eraseButton setSelected:YES];
    

然后我添加了[self.view setNeedsDisplay]; 以求好运。按钮仍然没有改变状态,但代码正在运行(我可以打断点并且它在方法上中断并且方法在 thread1 上运行)?!?有什么想法吗?

* 更新 2 *

好的,我已经弄清楚我做错了什么。我在没有正确引用视图控制器的情况下完成了上述所有操作。因此,尽管代码正在执行,但视图控制器的实例不正确,并且所有按钮句柄都为零。我需要在 viewDidLoad 中将以下内容添加到 myViewController.m:

myAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    appDelegate.myViewController = self;

现在可以了。快乐的日子...

【问题讨论】:

alexefish.com/post/522641eb31fa2a0015000002 【参考方案1】:

因为当您执行app.vCtrl = [[myViewController alloc] init]; 时,您实际上创建了UIViewController 的一个新实例,而不是屏幕上的原始实例。

我没有测试它们,但你可以通过以下方式实现你想要的:

通过 Interface Builder:UIViewController 中设置一个 IBOutlet myAppDelegate,将其连接到 Interface Builder 中的 ViewController,然后在 myAppDelegate 中创建一个方法更改它或使用myAppDelegate 直接访问它,因为它是一个属性。您现在可以在您的 BT 类中调用它,例如[app deselectEraseButton][app.myViewController deselectEraseButton] 或者如果按钮是 AppDelegate/VC 的属性,甚至可以对按钮执行某些操作。

通过代理:创建一个@protocol 为BT 类设置一个代理,这样它就可以在其他类中进行回调,例如@987654331 @。

通过 NSNotificationCenter: 使用 - (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender- (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo 来完成。这将适用于整个应用程序。

我相信以上三个已经有大量关于 SO 的代码示例,只需搜索它们,你就会得到你需要的。

【讨论】:

非常感谢您的帮助和快速回复。我认为可能缺少的部分是 myAppDelegate 中的方法代码。我已经这样做了,我遇到了同样的问题 - 代码在 myViewController 中执行,但按钮状态没有改变。是否有原因可以执行代码但按钮不改变状态?我也尝试了通知中心方法,但这似乎有点慢 - 按钮仅在 BT 方法完成后大约 5-10 秒后改变状态。 检查您是否在主线程中进行了所有 UI 更改?或尝试使用setNeedsDisplay 进行强制更新,看看是否有帮助。【参考方案2】:

我已根据原始问题进行了更新,其中包含 2 次更新,这些更新导致了最终的理解和解决方案。希望它可以帮助其他可能同样困惑的人!

【讨论】:

以上是关于在Objective-C,iOS中突出显示另一个类的按钮的主要内容,如果未能解决你的问题,请参考以下文章

IOS/Objective-C:调用另一个类(VC)方法不起作用

在 Storyboard 和 Swift 2 中禁用 UIButton 突出显示

当鼠标位于材质表中的一行上时,突出显示

如何检测按下的按钮并将其显示在另一个视图上? Objective-C

如何在 Objective-C 中保存另一个类正在使用的类对象?

IOS/objective-c/core-data:如何从相关实体获取属性