ZXingObjc barcode scanner in a tab bar throw errors - ios

i have a tab bar and navigation controller for my app. whenever i tap the scan tab, it kept throwing me Thread 1: EXC_BAD_ACCESS error on line:
ZXCapture.m
[output ZXQT(setDelegate:)ZXAV(setSampleBufferDelegate:)self
Here is my code:
tab bar:
TestScanViewController *scannerViewController=[[TestScanViewController alloc] initWithNibName:#"TestScanViewController" bundle:nil];
navigationController =[[UINavigationController alloc] initWithRootViewController:scannerViewController];
in the TestScanViewController.h:
#interface TestScanViewController : UIViewController <ZXCaptureDelegate>
#end
in the TestScanViewController.m:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import "TestScanViewController.h"
#interface TestScanViewController ()
#property (nonatomic, strong) ZXCapture* capture;
#property (nonatomic, weak) IBOutlet UILabel* decodedLabel;
#end
#implementation TestScanViewController
#pragma mark - View Controller Methods
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(#"%s",__PRETTY_FUNCTION__);
if (self.capture == nil) {
self.capture = [[ZXCapture alloc] init];
self.capture.delegate = self;
self.capture.rotation = 90.0f;
// Use the back camera
self.capture.camera = self.capture.back;
self.capture.layer.frame = self.view.bounds;;
[self.view.layer addSublayer:self.capture.layer];
[self.view bringSubviewToFront:self.decodedLabel];
}else{
[self.capture start];
[self.view.layer addSublayer:self.capture.layer];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(#"%s",__PRETTY_FUNCTION__);
[self.capture.layer removeFromSuperlayer];
[self.capture stop];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
#pragma mark - Private Methods
- (NSString*)displayForResult:(ZXResult*)result {
}
return [NSString stringWithFormat:#"Scanned!\n\nFormat: %#\n\nContents:\n%#", formatString, result.text];
}
#pragma mark - ZXCaptureDelegate Methods
- (void)captureResult:(ZXCapture*)capture result:(ZXResult*)result {
if (result) {
// We got a result. Display information about the result onscreen.
[self.decodedLabel performSelectorOnMainThread:#selector(setText:) withObject:[self displayForResult:result] waitUntilDone:YES];
// Vibrate
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}
- (void)captureSize:(ZXCapture*)capture width:(NSNumber*)width height:(NSNumber*)height {
}
#end
just like the examples codes from github:
https://github.com/TheLevelUp/ZXingObjC/blob/master/examples/BarcodeScanner/ViewController.m

I had the same problem. If you are targeting iOS version 6 or higher and using ARC, then the cause of the problem is an incomplete migration to ARC in ZXCapture.m.
Look around line 56 for this code:
#interface ZXCapture ()
#property (nonatomic, assign) dispatch_queue_t captureQueue;
#end
The assign is a leftover from before ARC days. It also causes a compiler warning, which was my clue to the solution.
To solve the problem, change the code into:
#interface ZXCapture ()
#property (nonatomic, strong) dispatch_queue_t captureQueue;
#end

Related

ZXingObjc Integration IOS ,but didn't work at all

I have integrated the ZXingObjc framework,and ViewController as the RootViewController.
the codes in ViewController.m follows:
#import <AudioToolbox/AudioToolbox.h>
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) ZXCapture *capture;
#property (nonatomic, weak) IBOutlet UIView *scanRectView;
#property (nonatomic, weak) IBOutlet UILabel *decodedLabel;
#end
#implementation ViewController
#pragma mark - View Controller Methods
- (void)dealloc {
[self.capture.layer removeFromSuperlayer];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.capture = [[ZXCapture alloc] init];
self.capture.camera = self.capture.back;
self.capture.focusMode = AVCaptureFocusModeContinuousAutoFocus;
self.capture.rotation = 90.0f;
self.capture.layer.frame = self.view.bounds;
[self.view.layer addSublayer:self.capture.layer];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.capture.delegate = self;
self.capture.layer.frame = self.view.bounds;
self.capture.scanRect = self.scanRectView.frame;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
#pragma mark - Private Methods
- (NSString *)barcodeFormatToString:(ZXBarcodeFormat)format {
switch (format) {
case kBarcodeFormatAztec:
return #"Aztec";
case kBarcodeFormatCodabar:
return #"CODABAR";
case kBarcodeFormatCode39:
return #"Code 39";
case kBarcodeFormatCode93:
return #"Code 93";
case kBarcodeFormatCode128:
return #"Code 128";
case kBarcodeFormatDataMatrix:
return #"Data Matrix";
case kBarcodeFormatEan8:
return #"EAN-8";
case kBarcodeFormatEan13:
return #"EAN-13";
case kBarcodeFormatITF:
return #"ITF";
case kBarcodeFormatPDF417:
return #"PDF417";
case kBarcodeFormatQRCode:
return #"QR Code";
case kBarcodeFormatRSS14:
return #"RSS 14";
case kBarcodeFormatRSSExpanded:
return #"RSS Expanded";
case kBarcodeFormatUPCA:
return #"UPCA";
case kBarcodeFormatUPCE:
return #"UPCE";
case kBarcodeFormatUPCEANExtension:
return #"UPC/EAN extension";
default:
return #"Unknown";
}
}
#pragma mark - ZXCaptureDelegate Methods
- (void)captureCameraIsReady:(ZXCapture *)capture
{
NSLog(#"%s,%d",__FUNCTION__,__LINE__);
}
- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result {
if (!result) return;
NSLog(#"%s,%d",__FUNCTION__,__LINE__);
// We got a result. Display information about the result onscreen.
NSString *formatString = [self barcodeFormatToString:result.barcodeFormat];
NSString *display = [NSString stringWithFormat:#"Scanned!\n\nFormat: %#\n\nContents:\n%#", formatString, result.text];
[self.decodedLabel performSelectorOnMainThread:#selector(setText:) withObject:display waitUntilDone:YES];
// Vibrate
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
[self.capture stop];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self.capture start];
});
}
#end
I found that the mothod - (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result doesn't work at all.
Next,the same codes i put it into the example of ZXingObjc,it works well.
I really don't know what's wrong with me.
Wish your help!
I had the same problem. In my situation, the view controller would launch, but would never detect a barcode. Turns out I needed to add '-ObjC' to 'Other Linker Flags'.
Reference: https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Articles/configuration.html
Did your Viewcontroller.h file adopt the ZXCapture protocol? Something like this:
//ViewController.h
#interface ViewController: NSObject <ZXCaptureDelegate> //<---- this guy
- (void)yourFunction;
- (void)anotherFunction;
#end
(I'm not sure what is its real name)

respondsToSelector Cannot be Called?

Sorry about the confusion.
What I want to do:
enter a string in a textfield in a view(EnterCommandViewController) and click save button, which will dismiss current view and go back to another view(DetectionViewController) and show the string in the UILabel in current view(DetectionViewController). So I have put define the delegate protocol in EnterCommandViewController, my question is that why the respondToSelector, which is used to check whether someone is listening does not work.
I am really a beginner in iOS, I am right now writing a delegate to send text got form UITextField to a UILabel, But I found that the respondToSelector cannot be called by using NSLog for testing.
Below is my code for reference:
EnterCommandViewController.h
#import <UIKit/UIKit.h>
#import "RscMgr.h"
#protocol EnterCommandDelegate <NSObject>
-(void) commandEntered:(NSString*)command;
#end
#interface EnterCommandViewController : UIViewController <RscMgrDelegate>
{
RscMgr* rscMgr;
__weak IBOutlet UITextField *inputTextField;
__unsafe_unretained id<EnterCommandDelegate> delegate;
}
-(void)sendMessage:(NSString*)message;
- (IBAction)cancelPressed;
- (IBAction)savePressed;
#property (nonatomic,assign)id delegate;
#end
EnterCommandViewController.m
#import "EnterCommandViewController.h"
#interface EnterCommandViewController () <UITextFieldDelegate>
{
#private
BOOL connected;
}
#end
#implementation EnterCommandViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
rscMgr = [[RscMgr alloc] init];
[rscMgr setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
inputTextField.text=#"";
[inputTextField becomeFirstResponder];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputTextField.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
inputTextField.delegate = nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cancelPressed {
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (IBAction)savePressed {
//is anyone listening
NSLog(#"the command is %#",inputTextField.text);
NSLog(#"Checking -- SomeMethod is listening");
if([delegate respondsToSelector:#selector(commandEntered:)]){
NSLog(#"SomeMethod is listening");
//send delegate function with the command entered by the user
[delegate commandEntered:inputTextField.text];
}
[self dismissViewControllerAnimated:YES completion:^{}];
}
DetectionViewController.h
#import <UIKit/UIKit.h>
#import "EnterCommandViewController.h"
#interface DetectionViewController : UIViewController <EnterCommandDelegate>{
__weak IBOutlet UILabel *showCommand;
}
- (IBAction)showSettings:(UIBarButtonItem *)sender;
#end
DetectionViewController.m
#import <Foundation/Foundation.h>
#import "DetectionViewController.h"
#implementation DetectionViewController
- (IBAction)showSettings:(UIBarButtonItem *)sender {
}
-(void) viewDidLoad{
[super viewDidLoad];
showCommand.text=#"";
EnterCommandViewController* enterCVC = [[EnterCommandViewController alloc] init];
enterCVC.delegate = self;
}
#pragma mark - EnterCommandDelegate function(s)
-(void) commandEntered:(NSString *)command{
// showCommand.text = command;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"command: %#",command);
[self->showCommand setText:command];
});
}
#end
AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
You are not setting the delegate properly.
EnterCommandViewController* enterCVC = [[EnterCommandViewController alloc] init];
enterCVC.delegate = self;
This is not the way of setting the delegate in your case, since you are not using the created instance of enterCVC, instead a new instance is created from the storyboard when you are transitioning toEnterCommandViewController `(From your comment its clear that you are using the storyboard for this).
So what you can do is you should the delegate from prepareForSegue in DetectionViewController like
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get reference to the destination view controller
EnterCommandViewController* enterCVC = [segue destinationViewController];
enterCVC.delegate = self;
}

failure of alloc and Init

So perhaps this is a beginner's mistake and super easy to you guys, but i really do not know how to solve it,really appreciate for any suggestions:
Right Now:
1: I have to ViewController: EnterCommandViewController and DetectionViewController
2: I wrote Delegate protocol in EnterCommandViewController and set DetectionViewController as its delegate.
3: About delegate: I have a inputTextField in the EnterCommandView and a "Save" bar button item on the top toolbar in this view. Once I click the save , current view will be dismissed and return back to DetectionView and show the NSString just entered in the UILabel in DetectionView.
Finally, My question is that Why After I alloc and init a EnterCommandViewController instance , that is enterCVS, the instance is still nil as show in end of my post.
Code:
EnterCommandViewController.h
#import <UIKit/UIKit.h>
#import "RscMgr.h"
#protocol EnterCommandDelegate <NSObject>
#optional
-(void) commandEntered:(NSString*)command;
#end
#interface EnterCommandViewController : UIViewController <RscMgrDelegate,EnterCommandDelegate>
{
RscMgr* rscMgr;
IBOutlet UITextField *inputTextField;
// DetectionViewController* detectionViewController;
// __unsafe_unretained id<EnterCommandDelegate> delegate;
}
-(void)sendMessage:(NSString*)message;
-(id)initWithDelegate:(id)delegateToBe;
- (IBAction)cancelPressed;
- (IBAction)savePressed;
#property (nonatomic,weak) id<EnterCommandDelegate> delegate; //assign replaced
#end
EnterCommandVIewController.m
#import "EnterCommandViewController.h"
#import "DetectionViewController.h"
#interface EnterCommandViewController () <UITextFieldDelegate>
{
#private
BOOL connected;
}
#end
#implementation EnterCommandViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
rscMgr = [[RscMgr alloc] init];
[rscMgr setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
[inputTextField becomeFirstResponder];
}
-(id)initWithDelegate:(id)delegateToBe{
if(self = [super init]){
delegate = delegateToBe;
}
return self;
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputTextField.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
inputTextField.delegate = nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITextFieldDelegate Methods
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[self sendMessage:textField.text];
textField.text = nil;
return NO;
}
#pragma mark - Serial Tx/Rx Methods Implementation
-(void) sendMessage:(NSString *)message{
if(connected == YES) {
[rscMgr writeString:message];
}
else{
NSLog(#"CableDisconnected!");
NSLog(#"Attempted To Send: %#",message);
}
}
- (IBAction)cancelPressed {
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (IBAction)savePressed {
//is anyone listening
if([[[UIDevice currentDevice]systemVersion] compare:#"7.0" options:NSNumericSearch] != NSOrderedAscending){
NSLog(#"SYStem version > 7.0");
}
if(delegate&&[delegate respondsToSelector:#selector(commandEntered:)]){
NSLog(#"SomeMethod is listening");
[delegate commandEntered:inputTextField.text];
}
[self dismissViewControllerAnimated:YES completion:nil]; //commened: ^{}
}
#pragma mark - RscMgrDelegate Methods Implementation
-(void) cableConnected:(NSString *)protocol{
inputTextField.text = #"cableConnected";
[rscMgr setBaud:9600];
[rscMgr open];
connected = YES;
}
-(void) cableDisconnected{
inputTextField.text = #"cableDisconnected";
connected = NO;
}
-(void) readBytesAvailable:(UInt32)length{}
-(void) portStatusChanged{}
#end
DetectionViewController.h
#import <UIKit/UIKit.h>
#import "EnterCommandViewController.h"
#interface DetectionViewController : UIViewController <EnterCommandDelegate>{
}
- (IBAction)showSettings:(UIBarButtonItem *)sender;
#property (nonatomic, strong) EnterCommandViewController* enterCVC;
#property (nonatomic, strong) IBOutlet UILabel *showReceivedCommand;
#end
DetectionViewController.m
#import <Foundation/Foundation.h>
#import "DetectionViewController.h"
#import "EnterCommandViewController.h"
#implementation DetectionViewController
#synthesize showReceivedCommand;
#synthesize enterCVC;
- (IBAction)showSettings:(UIBarButtonItem *)sender {
}
-(void) viewDidLoad{
[super viewDidLoad];
if(showReceivedCommand){
showReceivedCommand.text=#"Initial text";
NSLog(#"UILAbel in ViewDidload is not nil");
}else {
NSLog(#"UILAbel in viewDidload is nil");
}
enterCVC = [[EnterCommandViewController alloc] init];
if(enterCVC.delegate) NSLog(#"X nil");
[enterCVC setDelegate:self];
}
#pragma mark - EnterCommandDelegate function(s)
-(void)commandEntered:(NSString *)command{
dispatch_async(dispatch_get_main_queue(), ^{
if(showReceivedCommand){
NSLog(#"UILabel is not nil");
}else{NSLog(#"UILabel is nil");}
showReceivedCommand = [[UILabel alloc] init];
NSLog(#"command received: %#",command);
showReceivedCommand.text = command;
[showReceivedCommand setNeedsDisplay];
NSLog(#"text in showReceivedCommand is %#",showReceivedCommand.text);
});
}
#end
I set a break point at DetectionViewController.n --> ViewDidLoad() --> [enterCVC setDelegate:self];
I got:
self DetectionViewController * 0x15c50e850 0x000000015c50e850
UIViewController UIViewController
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
UIViewController UIViewController
rscMgr RscMgr * nil 0x0000000000000000
inputTextField UITextField * nil 0x0000000000000000
connected BOOL NO false
delegate id 0x0 0x0000000000000000
enterCVC = [[EnterCommandViewController alloc] init]
Try changing that to....
enterCVC = [[EnterCommandViewController alloc] initWithDelegate:self];

Access active Mediaplayer from DetailViewController in App Deligate UISplitViewController (MobileVLCKit)

Im currently developing a videostreaming iOS App with the MobileVLCKit framework. To navigate through the different transmitters I use the UISplitViewController. The App works fine until I lock the screen of the iPad 3. I Debugged the code and know that the player is still running in the background. I have to access the media player property (_mediaplayer) to stop the player if it gets resign or enters background in app deligate.
I have searched in the www and on stackoverflow, but it seems to be a little part that i might not see or misunderstand. I would be very pleased if someone could take a minute and help me spot the problem.
btw. Yeah my first post on SO, after nearly two years of using it :D
Question: How can I access the property in the appDeligate.m?
AppDeligate.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UISplitViewController *splitViewController;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) DetailViewController *viewController;
#end
AppDeligate.m
#import "AppDelegate.h"
#import "DetailViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
DetailViewController *thePlayer = [[splitViewController viewControllers] objectAtIndex:1];
if(thePlayer._mediaplayer.isPlaying == true) {
NSLog(#"Player is playing");
}
NSLog(#"Background");
}
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>
#property (strong, nonatomic) VLCMediaPlayer* _mediaplayer;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UIView *movieView;
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *masterPopoverController;
#end
#implementation DetailViewController
#synthesize _mediaplayer;
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
NSLog(#"setDetailItem");
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)mediaPlayerStateChanged:(NSNotification *)aNotification
{
VLCMediaPlayerState currentState = _mediaplayer.state;
/* Playback opening */
if (currentState == VLCMediaPlayerStateOpening) {
[self.indicator startAnimating];
NSLog(#"Openning");
}
/* or if playback ended */
if (currentState == VLCMediaPlayerStateEnded || currentState == VLCMediaPlayerStateStopped) {
NSLog(#"Stopped");
[self.indicator stopAnimating];
}
/* Playback buffering */
if (currentState == VLCMediaPlayerStateBuffering) {
NSLog(#"buffering");
[self.indicator startAnimating];
}
/* Playback buffering */
if (currentState == VLCMediaPlayerStatePlaying) {
NSLog(#"Playing");
[self.indicator stopAnimating];
}
}
- (void)configureView
{
NSLog(#"configureView");
// Update the user interface for the detail item.
if (self.detailItem) {
self.imageView.image = nil;
if(self._mediaplayer.isPlaying) {
// Stop active media
[self._mediaplayer stop];
}
// Set new url
self._mediaplayer.media = [VLCMedia mediaWithURL:[NSURL URLWithString:_detailItem]];
// Play new media
[self._mediaplayer play];
// Set radio image
if ([_detailItem rangeOfString:#"239.192.1"].location != NSNotFound) {
[self.imageView setImage:[[UIImage imageNamed:#"music.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
self.imageView.contentMode = UIViewContentModeCenter;
}
}
}
- (void)viewDidDisappear
{
NSLog(#"viewDidDisappear");
if (self._mediaplayer) {
#try {
[self._mediaplayer removeObserver:self forKeyPath:#"time"];
[self._mediaplayer removeObserver:self forKeyPath:#"remainingTime"];
}
#catch (NSException *exception) {
NSLog(#"we weren't an observer yet");
}
if (self._mediaplayer.media)
[self._mediaplayer stop];
if (self._mediaplayer)
self._mediaplayer = nil;
}
}
- (void)viewDidLoad
{
NSLog(#"viewDidLoad");
[super viewDidLoad];
// Hide navbar
[[self navigationController] setNavigationBarHidden:YES animated:YES];
// Background logo
[self.imageView setImage:[[UIImage imageNamed:#"background.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
self.imageView.contentMode = UIViewContentModeCenter;
// Init media player
[self initMediaplayer];
}
- (void)initMediaplayer
{
self._mediaplayer = [[VLCMediaPlayer alloc] init];
self._mediaplayer.delegate = self;
self._mediaplayer.drawable = self.movieView;
NSLog(#"Init VLC Player");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Split view
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
#end
Make splitViewController an instance variable in #interface and than change:
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
DetailViewController *thePlayer = [[splitViewController viewControllers] objectAtIndex:1];
[thePlayer._mediaplayer stop];
NSLog(#"Resign");
}
This is the final code which worked for me. Feel free to use!
AppDelegate.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) DetailViewController *viewController;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "DetailViewController.h"
#interface AppDelegate () {
UISplitViewController *splitViewController;
UINavigationController *navigationController;
VLCMedia *currentPlayback;
}
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
splitViewController = (UISplitViewController *)self.window.rootViewController;
navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(#"WillResignActive");
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"DidEnterBackground");
DetailViewController *dvc = (DetailViewController *)navigationController.topViewController;
if (dvc._mediaplayer.isPlaying) {
[dvc._mediaplayer stop];
NSLog(#"Mediaplyer stopped");
currentPlayback = dvc._mediaplayer.media;
NSLog(#"Saved current playback");
while (dvc._mediaplayer.isPlaying) {
[NSThread sleepForTimeInterval:0.1];
}
}
if (dvc._mediaplayer != nil) {
dvc._mediaplayer = nil;
NSLog(#"Set player to nil");
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"WillenterForeground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"DidBecomeActive");
DetailViewController *dvc = (DetailViewController *)navigationController.topViewController;
if (dvc._mediaplayer == nil) {
dvc._mediaplayer = [[VLCMediaPlayer alloc] init];
dvc._mediaplayer.delegate = self;
dvc._mediaplayer.drawable = dvc.movieView;
NSLog(#"init mediaplayer");
}
if (currentPlayback != nil || dvc._mediaplayer.media == nil) {
dvc._mediaplayer.media = currentPlayback;
NSLog(#"set current playback media");
}
if (dvc._mediaplayer.media != nil || dvc._mediaplayer.isPlaying == false) {
[dvc._mediaplayer play];
NSLog(#"play");
}
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import <MobileVLCKit/MobileVLCKit.h>
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>
#property (strong, nonatomic) IBOutlet UITapGestureRecognizer *tapGestureRecognizer;
#property (strong, nonatomic) VLCMediaPlayer* _mediaplayer;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UIView *movieView;
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *masterPopoverController;
#property (strong, nonatomic) UIBarButtonItem *barButton;
#end
#implementation DetailViewController
#synthesize _mediaplayer;
- (IBAction)handleTap:(UITapGestureRecognizer *)sender {
[_barButton.target performSelector: _barButton.action withObject: _barButton];
}
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
NSLog(#"setDetailItem");
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)mediaPlayerStateChanged:(NSNotification *)aNotification
{
VLCMediaPlayerState currentState = _mediaplayer.state;
/* Playback opening */
if (currentState == VLCMediaPlayerStateOpening) {
[self.indicator startAnimating];
NSLog(#"Openning");
}
/* or if playback ended */
if (currentState == VLCMediaPlayerStateEnded || currentState == VLCMediaPlayerStateStopped) {
NSLog(#"Stopped");
[self.indicator stopAnimating];
}
/* Playback buffering */
if (currentState == VLCMediaPlayerStateBuffering) {
NSLog(#"buffering");
[self.indicator startAnimating];
}
/* Playback buffering */
if (currentState == VLCMediaPlayerStatePlaying) {
NSLog(#"Playing");
[self.indicator stopAnimating];
}
}
- (void)configureView
{
NSLog(#"configureView");
// Update the user interface for the detail item.
if (self.detailItem) {
self.imageView.image = nil;
if(_mediaplayer.isPlaying) {
// Stop active media
[_mediaplayer stop];
}
// Set new url
_mediaplayer.media = [VLCMedia mediaWithURL:[NSURL URLWithString:_detailItem]];
// Play new media
[_mediaplayer play];
// Set radio image
if ([_detailItem rangeOfString:#"239.192.1"].location != NSNotFound) {
[self.imageView setImage:[[UIImage imageNamed:#"music.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
self.imageView.contentMode = UIViewContentModeCenter;
}
}
}
- (void)viewDidLoad
{
NSLog(#"viewDidLoad");
[super viewDidLoad];
// Hide navbar
[[self navigationController] setNavigationBarHidden:YES animated:YES];
// Show navbar
[_barButton.target performSelector: _barButton.action withObject: _barButton afterDelay:1];
// Background logo
[self.imageView setImage:[[UIImage imageNamed:#"background.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
self.imageView.contentMode = UIViewContentModeCenter;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Split view
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
_barButton = barButtonItem;
}
#end

ObjectiveC setting image when thread finished

I have a button which I'm trying to set the image for when a thread is finished. My code may seem useless to just change the image button but this is for practise and going onto a bigger thing.
Goal: Set the image for the b0 as button_x.png (found in the project).
Issue: The button image is not changing, if I make a connection between the button found on the storyboard to the viewController button declaration I get a crash with -[UIButton setImage:]: unrecognized selector sent to instance 0x8b4c270.
Thank you.
ViewController.h:
#interface ViewController : UIViewController {
IBOutlet UIButton *b0;
Game *instanceOfGame;
}
#property (nonatomic, strong) UIButton *b0;
#property (nonatomic, strong) Game *instanceOfGame;
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize instanceOfGame;
#synthesize b0;
static NSString *postName = #"123";
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(post:) name:postName object:nil];
instanceOfGame = [[Game alloc] init];
[instanceOfGame start];
}
- (void) post: (NSNotification *) result {
NSNumber *str = [result object];
if (str == 0) {
[self.b0 performSelectorOnMainThread:#selector(setImage: ) withObject:[UIImage imageNamed:#"button_x.png"] waitUntilDone:NO];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Game.h:
#import <Foundation/Foundation.h>
#interface Game : NSObject
#property (nonatomic, strong) NSNumber *choice;
#property (nonatomic, strong) NSNotificationCenter *ns;
-(void) start;
#end
Game.m:
#import "Game.h"
#implementation Game
NSNotificationCenter *ns;
#synthesize ns;
#synthesize choice;
static NSString *postName = #"123";
-(id) init {
if (self = [super init]) {
ns = [NSNotificationCenter defaultCenter];
}
return self;
}
-(void) start {
[self performSelectorInBackground:#selector(loadData) withObject:Nil];
}
-(void) loadData {
choice = 0;
[ns postNotificationName:postName object:choice];
}
#end
UIButton doesn't have a setImage: function, hence the exception being thrown.
It does have this function though:
- (void)setImage:(UIImage *)image forState:(UIControlState)state
Try replacing:
[self.b0 performSelectorOnMainThread:#selector(setImage: ) withObject:[UIImage imageNamed:#"button_x.png"] waitUntilDone:NO];
With a similar sort of implementation done using GCD calling the correct function:
dispatch_async(dispatch_get_main_queue(), ^{
[self.b0 setImage:[UIImage imageNamed:#"button_x.png"] forState:UIControlStateNormal];
});
#Colin Cornaby saying write.
UIButton doesn't have setImage method.
You can also use the same existing code. just update below line
[self.b0 performSelectorOnMainThread:#selector(setImage: ) withObject:[UIImage imageNamed:#"button_x.png"] waitUntilDone:NO];
as
[self performSelectorOnMainThread:#selector(setImage: ) withObject:[UIImage imageNamed:#"ListDropDown.png"] waitUntilDone:NO];
and then define method setImage:
-(void)setImage:(UIImage *)img
{
[self.bo setImage:img forState:UIControlStateNormal];
}
I hope it will work for you
Try this,
if (str == 0) {
dispatch_sync(dispatch_get_main_queue(), ^{
[self.b0 setImage:[UIImage imageNamed:#"button_x.png"] forState:UIControlStateNormal];
});
}

Resources