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)
Related
I am not getting Chat Bubble in JSQMessageViewController but not able to get what to method to be add to get chat bubble in my chat page in IOS I am getting only Textbox and send button when I type text and click send not getting bubbles I am new please help me.
// .h File content
// ChatpageViewController.h
// ChatApp
#import <UIKit/UIKit.h>
#import <JSQMessagesViewController/JSQMessages.h>
#import <JSQMessagesViewController.h>
#import "JSQMessagesCollectionViewFlowLayout.h"
#import "JSQMessages.h"
#import "JSQPhotoMediaItem.h"
#import "JSQLocationMediaItem.h"
#import "JSQVideoMediaItem.h"
#import "JSQMessagesMediaViewBubbleImageMasker.h"
#import "JSQMessagesAvatarImage.h"
#import "JSQMessagesAvatarImageFactory.h"
#import "JSQMessagesBubbleImage.h"
#import "JSQMessagesBubbleImageFactory.h"
#import "UIImage+JSQMessages.h"
#interface ChatpageViewController : JSQMessagesViewController<JSQMessagesCollectionViewDataSource,JSQMessagesCollectionViewDelegateFlowLayout,JSQMessagesCollectionViewCellDelegate,JSQMessageData,JSQMessageMediaData,JSQMessageAvatarImageDataSource,JSQMessageBubbleImageDataSource>
#property(nonatomic,strong)NSDictionary * receivedict;
#property (strong, nonatomic) IBOutlet UILabel *name;
#property (strong, nonatomic) IBOutlet UILabel *mobile;
- (IBAction)cancelbtn:(id)sender;
#end
M File starts from here
//
// ChatpageViewController.m
// ChatApp
//
#import "ChatpageViewController.h"
#interface ChatpageViewController ()
{
}
#end
#implementation ChatpageViewController
#synthesize receivedict,name,mobile;
-(void)viewWillAppear:(BOOL)animated
{
self.collectionView.collectionViewLayout.springinessEnabled = YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.navigationController setNavigationBarHidden:YES animated:YES];
NSLog(#"%#",receivedict);
name.text = [receivedict objectForKey:#"Name"];
id.text =[receivedict objectForKey:#"Id"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSString *)senderId
{
return [receivedict objectForKey:#"Id"];
}
- (NSString *)senderDisplayName
{
return [receivedict objectForKey:#"Name"];
}
- (NSDate *)date
{
return 18/03/2016;
}
- (void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date
{
[JSQSystemSoundPlayer jsq_playMessageSentSound];
JSQMessage *message = [[JSQMessage alloc] initWithSenderId:senderId
senderDisplayName:senderDisplayName
date:date
text:text];
// [demoData.messages addObject:message];
[self finishSendingMessageAnimated:YES];
NSLog(#"%#",message);
}
- (IBAction)cancelbtn:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
#end
There is lots of problem in your code .. You are not implementing all JSQ methods .. kindly check how to integrate JSQMessageViewController and than for bubbles that is you main question check answer below :-
You have to use JSQMessagesBubbleImage class to get bubbles like ...
in .h file define
#property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageData;
#property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageData;
in .m file in viewDidLoad
JSQMessagesBubbleImageFactory *bubbleFactory = [[JSQMessagesBubbleImageFactory alloc] init];
self.outgoingBubbleImageData = [bubbleFactory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];
self.incomingBubbleImageData = [bubbleFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
than provide JSQMessages CollectionView DataSource
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
JSQMessage *message = [messages objectAtIndex:indexPath.item];
if ([message.senderId isEqualToString:self.senderId]) {
return self.outgoingBubbleImageData;
}
return self.incomingBubbleImageData;
}
I tried after adding the bellow methods in my coding then I have got the bubble with the bellow post other functions - (void)didPressSendButton:(UIButton *)button etc.
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath
{
JSQMessage *message = [fularray objectAtIndex:indexPath.item];
if ([message.senderId isEqualToString:self.senderId]) {
return self.outgoingBubbleImageData;
}
return self.incomingBubbleImageData;
}
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return [JSQMessagesAvatarImageFactory avatarImageWithUserInitials:#"JL" backgroundColor:[UIColor blueColor] textColor:[UIColor whiteColor] font:[UIFont systemFontOfSize:12.0] diameter:30.0];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [fularray count];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return fularray[indexPath.row];
}
I get the exc_bad_access error when running my project and trying to change the picker.
The error is occurring on
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
Below is my code. From reading the other SO articles I realize I am probably not retaining my variable. I'm new and learning and appreciate the help.
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#class RootViewController;
#interface AddConditionViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UITextField *txtConditionDetail;
IBOutlet UITextField *txtConditionArea;
IBOutlet UIPickerView *conditionNamesPicker;
NSMutableArray *names;
NSMutableArray *conditionDefs;
RootViewController *rvc;
NSString *conditionName;
}
#property (retain, nonatomic) IBOutlet UIPickerView *conditionNamesPicker;
#property (nonatomic,assign) RootViewController *rvc;
#property (nonatomic, retain) NSString *conditionName;
#property (nonatomic,assign) NSMutableArray *names;
#property (nonatomic,assign) NSMutableArray *conditionDefs;
#end
#import "AddConditionViewController.h"
#import "ConditionsAppDelegate.h"
#import "Condition.h"
#import "ConditionDef.h"
#import "Formula.h"
#implementation AddConditionViewController
#synthesize rvc, conditionNamesPicker, names, conditionDefs, conditionName;
/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Add Condition";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel_Clicked:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self action:#selector(save_Clicked:)] autorelease];
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
conditionDefs = appDelegate.getConditionDefs;
self.names = [NSMutableArray arrayWithCapacity:[conditionDefs count]];
for (ConditionDef *def in conditionDefs) {
NSString *condition_name = def.condition_name;
if (!condition_name) {
condition_name = #"<Unknown Account>";
}
[names addObject:condition_name];
}
self.conditionNamesPicker.dataSource = self;
self.conditionNamesPicker.delegate = self;
NSLog(#"LINE 48");
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Set the textboxes to empty string.
txtConditionArea.text = #"";
txtConditionDetail.text = #"";
//Make the Category name textfield to be the first responder.
[txtConditionArea becomeFirstResponder];
NSLog(#"LINE 63");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSLog(#" LINE 87 - COUNT OF CONDITION DEFS TO SHOW = %i", names.count);
[conditionNamesPicker setDataSource:self];
return [names count];
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
// NSLog(#"LINE 94 - here is the bug: conditionDefs[row] %#", names[row]);
return names[row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
conditionName = names[row];
}
- (void) save_Clicked:(id)sender {
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a Condition Object.
Condition *c = [[Condition alloc] init];
NSInteger newId = c.getNextConditionId;
Condition *cond = [[Condition alloc] initWithPrimaryKey:newId];
cond.condition_area = txtConditionArea.text;
cond.condition_detail = txtConditionDetail.text;
cond.condition_name = conditionName;
//Add the object
// [appDelegate addCondition:cond];
[appDelegate populateFromDatabase];
// ADD TO THE ARRAY:
// [cvc.categories addObject:cond];
// [cvc.Conditions addObject:cond];
rvc.Conditions = [appDelegate activeConditions];
// UPDATE THE TABLEVIEW
[rvc.tableView reloadData];
// release
[cond release];
[c release];
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (void) cancel_Clicked:(id)sender {
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
NSLog(#"LINE 159");
[theTextField resignFirstResponder];
return YES;
}
- (void)dealloc {
[txtConditionArea release];
[txtConditionDetail release];
[conditionNamesPicker release];
[super dealloc];
}
#end
Please change the property assign toretain for names property. And other array or those object inheriting fromNSObject. It is an object and you are keeping it as assign property. Use assign only for primitive data type. Try this and let me know.
You are setting the data source of PickerView in one the DataSource methods. This is not valid. Remove the below line
[conditionNamesPicker setDataSource:self];
from function:
numberOfRowsInComponent:
You are setting it again.
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];
my error it No visible #interface for 'WHMailActivity' declares the selector 'activityDidFinish:'
I get a one night but I did not succeed. . . Why are so used elsewhere but I can not. . .
Which I hope to help me. . .
Thanks in advance !
this it my .h
#import <Foundation/Foundation.h>
#import <MessageUI/MessageUI.h>
#import "WHMailActivityItem.h"
#interface WHMailActivity : UIViewController
#end
and this it my .m
#import "WHMailActivity.h"
#interface WHMailActivity() <MFMailComposeViewControllerDelegate>
#property (nonatomic, strong)WHMailActivityItem *activityItem;
#end
#implementation WHMailActivity
#pragma mark - UIActivity Overrides
- (NSString *)activityType {
return NSStringFromClass([self class]);
}
- (NSString *)activityTitle {
return NSLocalizedString(#"Mail", #"title for Mail activity item");
}
- (UIImage *)activityImage {
return [UIImage imageNamed:#"mailActivity.png"];
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
if (![MFMailComposeViewController canSendMail]) {
return NO;
}
for (id item in activityItems) {
if ([item isKindOfClass:[WHMailActivityItem class]]) {
return YES;
}
}
return NO;
}
- (void)prepareWithActivityItems:(NSArray *)activityItems {
for (id item in activityItems) {
if ([item isKindOfClass:[WHMailActivityItem class]]){
self.activityItem = item;
}
}
}
- (UIViewController *)activityViewController {
MFMailComposeViewController *composeController = [[MFMailComposeViewController alloc] init];
if (self.activityItem.onMailActivitySelected) {
self.activityItem.onMailActivitySelected(composeController);
}
composeController.mailComposeDelegate = self;
return composeController;
[self performSelector:#selector(mailComposeController)];
}
#pragma mark - MFMailComposeViewControllerDelegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self activityDidFinish:result == MFMailComposeResultSent];
}
#end
In your .h file you have:
#interface WHMailActivity : UIViewController
but it should be:
#interface WHMailActivity : UIActivity
assuming the class is a custom UIActivity.
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