Objective-C WKWebView: didFinish not triggering when WebView finishes loading - ios

My app is Objective-C, and I'm migrating little by little, so I need help with Objective-C, not Swift.
I'm migrating UIWebView to WKWebView and having problems to make didFinish to work.
This the class where I use the WebView, TMAnswerView:
#import "TMAnswerView.h"
#import "TMConsts.h"
#import "TMPersistanceManager.h"
#import <WebKit/WebKit.h>
#interface TMAnswerView () <WKNavigationDelegate>
//UIWebViewDelegate
#end
#implementation TMAnswerView.m
-(void)customInit{
}
-(void)setAnswer:(TMAnswerModel *)answer{
_answer = answer;
float font = 17;
NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
if([type isEqual:SettingsFontSizeType1]){
font = font * 0.75;
}else if([type isEqual:SettingsFontSizeType3]){
font = font * 1.25;
}else if([type isEqual:SettingsFontSizeType4]){
font = font * 1.5;
}else if([type isEqual:SettingsFontSizeType5]){
font = font * 2;
}
NSString *htmlBody = [TMUtils getHTMLStringForMath:[answer.answer stringByReplacingOccurrencesOfString:#"$$" withString:#"$"] andFontSize:(int)font];
[_answerWebView loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:#"%#/", [[NSBundle mainBundle] bundlePath]]]];
_answerWebView.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
}
#pragma mark - click listeners
- (IBAction)onCheckButton:(id)sender {
if(_viewControllerType != TMMainTestViewConstrollerTypeDoTest){
return;
}
_checkButton.selected = !_checkButton.selected;
if(_delegate){
[_delegate onCheckChanged:_answer];
}
}
- (void)webView:(WKWebView *)webView
didFinishNavigation:(WKNavigation *)navigation{
[self setWebViewHeight];
}
//-(void)webViewDidFinishLoad:(WKWebView *)webView{
// [self setWebViewHeight];
//}
-(void) setWebViewHeight{
CGSize fittingSize = [_answerWebView sizeThatFits:CGSizeZero];
_heightOfWebView.constant = fittingSize.height;
}
#end
Here I've replaced UIWebView delegate by WKNavigationDelegate. I have to mention that is working fine with the old webViewDidFinishLoad of the UIWebView.
TMAnswerView.h:
#import "TMCustomView.h"
#import "TMAnswerModel.h"
#import "TMMainTestViewController.h"
#import <WebKit/WebKit.h>
#protocol TMAnswerViewProtocol <NSObject>
-(void) onCheckChanged:(TMAnswerModel*) answer;
#end
#interface TMAnswerView : TMCustomView
#property (nonatomic, strong) TMAnswerModel *answer;
#property (weak, nonatomic) IBOutlet UIButton *checkButton;
#property (weak, nonatomic) IBOutlet WKWebView *answerWebView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfWebView;
#property (weak, nonatomic) id<TMAnswerViewProtocol> delegate;
#property (nonatomic) TMMainTestViewConstrollerType viewControllerType;
-(void) setWebViewHeight;
#end
And finally in the storyboard I've added a WebKitView element in replacement of the old UIWebView.
I also tried with didFinishNavigation to no avail.
I checked this next page as reference:
WKWebView
Is there anything wrong in my code? How can I make the didFinish event trigger?
Edit 1
I also tried:
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
[self setWebViewHeight];
}
to no avail.
Edit 2
This is the class where the WKWebView is load, TMQuestionView:
#import "TMQuestionView.h"
#import "TMColors.h"
#import "TMDBManager.h"
#import "TMConsts.h"
#import "TMAnswerModel.h"
#import "TMAnswerView.h"
#import "TMViewUtils.h"
#import "TMPersistanceManager.h"
#import "TMImagePreviewView.h"
#import <WebKit/WebKit.h>
#interface TMQuestionView () <TMAnswerViewProtocol, WKNavigationDelegate>
#property (weak, nonatomic) IBOutlet WKWebView *webView;
#property (weak, nonatomic) IBOutlet UIView *answersView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *webviewHeight;
#property (weak, nonatomic) IBOutlet UIView *viewForLoading;
#property (weak, nonatomic) IBOutlet UIView *loadingView;
#property (weak, nonatomic) IBOutlet WKWebView *webviewExplanations;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *webviewExplanationsHeight;
#property (nonatomic) BOOL isExplanationsVisible;
#property (nonatomic, strong) NSMutableArray *images;
#property (nonatomic, strong) NSString *tempic;
#end
#implementation TMQuestionView
-(void)customInit{
[[CSLoadingManager sharedManager] addLoadingViewToView:_viewForLoading withColor:TMBaseColor(1)];
_images = [NSMutableArray new];
}
-(void)setQuestion:(TMQuestionModel *)question{
_question = question;
float font = 17;
NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
if([type isEqual:SettingsFontSizeType1]){
font = font * 0.75;
}else if([type isEqual:SettingsFontSizeType3]){
font = font * 1.25;
}else if([type isEqual:SettingsFontSizeType4]){
font = font * 1.5;
}else if([type isEqual:SettingsFontSizeType5]){
font = font * 2;
}
[_images addObjectsFromArray:[TMUtils getImagesFromQuestion:question.question]];
[_images addObjectsFromArray:[TMUtils getImagesFromQuestion:question.instructions]];
NSString *htmlString = question.question;
if(question.instructions.length > 0 && ![question.instructions isEqualToString:#"(null)"]){
htmlString = [NSString stringWithFormat:#"%#<br/>%#", question.instructions, question.question];
}
NSString *htmlBody = [TMUtils getHTMLStringForMath:htmlString andFontSize:(int)font];
htmlBody = [htmlBody stringByReplacingOccurrencesOfString:#"<center>" withString:#"<p style='text-align:center;'>"];
htmlBody = [htmlBody stringByReplacingOccurrencesOfString:#"</center>" withString:#"</p>"];
_tempic = htmlBody;
[_webView loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:#"%#/", [[NSBundle mainBundle] bundlePath]]]];
_webView.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
_answersView.hidden = YES;
[[TMDBManager sharedManager] getAnswersForQuestion:_question completition:^(NSDictionary *dict) {
NSArray *temp = [dict objectForKey:DBReturnAnswers];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"answerNumber" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
self->_answers = [temp sortedArrayUsingDescriptors:sortDescriptors];
[self setViewAnswers];
}];
}
-(void) setExplanations{
_isExplanationsVisible = YES;
float font = 17;
NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
if([type isEqual:SettingsFontSizeType1]){
font = font * 0.75;
}else if([type isEqual:SettingsFontSizeType3]){
font = font * 1.25;
}else if([type isEqual:SettingsFontSizeType4]){
font = font * 1.5;
}else if([type isEqual:SettingsFontSizeType5]){
font = font * 2;
}
NSString *htmlString = _question.explanation;
NSString *htmlBody = [TMUtils getHTMLStringForMath:htmlString andFontSize:(int)font];
[_webviewExplanations loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:#"%#/", [[NSBundle mainBundle] bundlePath]]]];
_webviewExplanations.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
}
-(void)setRecordAnswer:(TMRecordAnswerModel *)recordAnswer{
_recordAnswer = recordAnswer;
}
-(void) setViewAnswers{
int i = 0;
float font = 17;
NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
if([type isEqual:SettingsFontSizeType1]){
font = font * 0.75;
}else if([type isEqual:SettingsFontSizeType3]){
font = font * 1.25;
}else if([type isEqual:SettingsFontSizeType4]){
font = font * 1.5;
}else if([type isEqual:SettingsFontSizeType5]){
font = font * 2;
}
for(TMAnswerModel *item in _answers){
TMAnswerView *view = [[TMAnswerView alloc] init];
view.translatesAutoresizingMaskIntoConstraints = NO;
[_answersView addSubview:view];
[[view.leadingAnchor constraintEqualToAnchor:_answersView.leadingAnchor constant:0] setActive:YES];
[[view.rightAnchor constraintEqualToAnchor:_answersView.rightAnchor constant:0] setActive:YES];
if(i == 0){
[[view.topAnchor constraintEqualToAnchor:_answersView.topAnchor constant:0] setActive:YES];
}else{
UIView *lastView = [[_answersView subviews] objectAtIndex:i-1];
[[view.topAnchor constraintEqualToAnchor:lastView.bottomAnchor constant:0] setActive:YES];
}
view.answer = item;
view.delegate = self;
view.viewControllerType = _viewControllerType;
if(_recordAnswer){
if(item.isCorrect == 1){
if([_recordAnswer.selectedAnswerId isEqualToString:item.answerId]){
[view.checkButton setImage:[UIImage imageNamed:#"checkbox_checked"] forState:UIControlStateNormal];
}else{
[view.checkButton setImage:[UIImage imageNamed:#"checkbox_checked_gray"] forState:UIControlStateNormal];
}
}else{
if([_recordAnswer.selectedAnswerId isEqualToString:item.answerId]){
[view.checkButton setImage:[UIImage imageNamed:#"checkbox_error"] forState:UIControlStateNormal];
}
}
}
i++;
if(i == [_answers count]){
[[view.bottomAnchor constraintEqualToAnchor:_answersView.bottomAnchor constant:0] setActive:YES];
}
}
}
-(void)onCheckChanged:(TMAnswerModel *)answer{
for (TMAnswerView *item in [_answersView subviews]){
if(![item.answer isEqual:answer]){
if(item.checkButton.selected){
item.checkButton.selected = NO;
}
}
}
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
[self setHeightOfWebView];
}
//-(void)webViewDidFinishLoad:(WKWebView *)webView{
// [self setHeightOfWebView];
//}
-(TMAnswerModel*) getSelectedAnswer{
for (TMAnswerView *item in [_answersView subviews]){
if(item.checkButton.selected){
return item.answer;
}
}
return nil;
}
-(void) setHeightOfWebView{
_viewForLoading.hidden = YES;
_loadingView.hidden = YES;
CGSize fittingSize = [_webView sizeThatFits:CGSizeZero];
_webviewHeight.constant = fittingSize.height;
_answersView.hidden = NO;
for(UIView *item in [_answersView subviews]){
if([item isKindOfClass:[TMAnswerView class]]){
[((TMAnswerView*) item) setWebViewHeight];
}
}
if(_isExplanationsVisible){
CGSize fittingSizeExplanations = [_webviewExplanations sizeThatFits:CGSizeZero];
_webviewExplanationsHeight.constant = fittingSizeExplanations.height;
}
}
- (IBAction)onButtonAboveWebViewClicked:(id)sender {
if([_images count] > 0){
TMImagePreviewView *view = [[TMImagePreviewView alloc] initWithFrame:CGRectMake(0, 0, kAppWidth, kAppHeight)];
[view setImages:_images];
[[[self superview] superview] addSubview:view];
[view fadeIn];
}
}
- (IBAction)onButtonTemp:(id)sender forEvent:(UIEvent *)event {
NSSet *touches = [event touchesForView:sender];
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:[sender superview]];
NSLog(#"%#", NSStringFromCGPoint(touchPoint));
long htmlLength = _tempic.length;
long heightOfWebView = _webView.frame.size.height;
double percentTouch = (double)touchPoint.y / (double)heightOfWebView;
int index = 0;
for(NSString *imageStr in _images){
NSString *match = [[imageStr componentsSeparatedByString:#"/"] objectAtIndex:1];
NSRange rangeOfImage = [_tempic rangeOfString:match];
double percentText = (double) rangeOfImage.location / (double)htmlLength;
if(percentText > percentTouch){
break;
}
index++;
}
NSLog(#"STOP");
}
#end

May be you can add this in TMAnswerView.setAnswer :
-(void)setAnswer:(TMAnswerModel *)answer {
...
// set self as navigationDelegate for the webView
_answerWebView.navigationDelegate = self;
[_answerWebView loadHTMLString:htmlBody...
...

Related

How to retrieve data properly using realm

I had a problem to retrieve data using realm. What i wanna do is caching the data so that i can use it when user first load the app or user does not have internet connection. Below is the logic what i wanna do.
request from fb api -> fb return 10 data -> display returned data and cache returned data -> if user doesn't have internet connection display cache data or if user have internet connection fetch new data.
below is my code :
FBVideo.h
#import <Realm/Realm.h>
#interface FBVideo : RLMObject
#property (nonatomic, strong) NSString *pageBefore;
#property (nonatomic, strong) NSString *pageAfter;
#property (nonatomic, strong) NSString *thumbnailsURI;
#property (nonatomic, strong) NSString *titleDescription;
#property NSString *id;
#end
FBVideo.m
#import "FBVideo.h"
#implementation FBVideo
+ (NSString *)primaryKey {
return #"id";
}
// Specify default values for properties
+ (NSDictionary *)defaultPropertyValues {
return #{#"pageBefore":#"", #"pageAfter":#"", #"thumbnailsURI":#"", #"titleDescription":#""};
}
+ (NSArray *)ignoredProperties {
return #[];
}
#end
PageVideosCVC.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import "FBVideo.h"
#interface PageVideosCVC : UICollectionViewController
#property (strong, nonatomic) NSMutableArray *videoArray;
#property (strong, nonatomic) NSString *pageID;
#property (strong, nonatomic) NSString *pageName;
#property (strong, nonatomic) MPMoviePlayerController *playerController;
#property (assign, nonatomic) CATransform3D initialTransformation;
#property (nonatomic, strong) NSMutableSet *shownIndexes;
//#property (strong, nonatomic) FBVideo *fbVideoRealm;
#end
PageVideosCVC.m
#import "PageVideosCVC.h"
#import "facebook.h"
#import "MBProgressHUD.h"
#import "Reachability.h"
#import <AFNetworking/AFNetworking.h>
#import <AVFoundation/AVFoundation.h>
#import <SDWebImage/UIImageView+WebCache.h>
#import <QuartzCore/QuartzCore.h>
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#interface PageVideosCVC () <UICollectionViewDataSource,UICollectionViewDelegate> {
NSString *pageBefore;
NSString *pageAfter;
NSString *thumbnailsURI;
Reachability *internetReachable;
NSDictionary *videoInfoToSaveInRealm;
// RLMResults *videoResultsFrom
}
#end
#implementation PageVideosCVC
#synthesize videoArray;
static NSString * const reuseIdentifier = #"Cell";
- (void) viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
videoArray = [NSMutableArray array];
/* Make a card effect, rotate the angle of the collectionviewcell to -15
1) Start with an identity transform, which is a fancy math term for “do nothing.”
2) Call CATransform3DRotate to apply a rotation of -15 degrees (in radians), where the negative value indicates a clockwise rotation.
3) Apply the rotation around the axis 0.0, 0.0, 1.0; this represents the z-axis, where x=0, y=0, and z=1.
4) Applying just the rotation to the card isn’t enough, as this simply rotates the card about its center. To make it look like it’s tipped over on a corner, add a translation or shift where the negative values indicate a shift up and to the left.
*/
CGFloat rotationAngleDegrees = -15;
CGFloat rotationAngleRadians = rotationAngleDegrees * (M_PI/180);
CGPoint offsetPositioning = CGPointMake(-20, -20);
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, rotationAngleRadians, 0.0, 0.0, 1.0);
transform = CATransform3DTranslate(transform, offsetPositioning.x, offsetPositioning.y, 0.0);
_initialTransformation = transform;
_shownIndexes = [NSMutableSet set];
}
- (void)viewWillAppear:(BOOL)animated {
UINavigationBar *navBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
navBar.barTintColor = UIColorFromRGB(0x266593);
// Altering the font style of the navigation bar title
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1);
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName,
shadow, NSShadowAttributeName,
[UIFont fontWithName:#"HelveticaNeue-CondensedBlack" size:21.0], NSFontAttributeName, nil]];
[self.view addSubview: navBar];
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Down Arrow.png"] style:UIBarButtonItemStyleBordered target:self action:#selector(backButtonTapped:)];
// UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithTitle:#"Back"
// style:UIBarButtonItemStylePlain
// target:self
// action:#selector(backButtonTapped:)];
[cancelItem setTintColor:[UIColor whiteColor]];
// UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:#"Done"
// style:UIBarButtonItemStyleBordered
// target:self action:nil];
NSString *selectedPageName = [[NSString alloc] initWithFormat:#"%#", self.pageName];
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:selectedPageName];
// navItem.rightBarButtonItem = doneItem;
navItem.leftBarButtonItem = cancelItem;
navBar.items = [NSArray arrayWithObjects: navItem,nil];
[UIBarButtonItem appearance].tintColor = [UIColor blueColor];
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[self loadVideo:#"a" pagesID:self.pageID];
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if ([pageBefore isEqual:pageBefore]) {
return videoArray.count;
}
return videoArray.count + 1;
}
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [videoArray count] - 1) {
NSLog(#"page after : %#", pageAfter);
[self loadVideo:pageAfter pagesID:self.pageID];
}
if (![self.shownIndexes containsObject:indexPath]) {
[self.shownIndexes addObject:indexPath];
// Transform collectionviewcell layer
UIView *card = [(UICollectionViewCell*)cell contentView];
card.layer.transform = self.initialTransformation;
card.layer.opacity = 0.5;
[UIView animateWithDuration:0.5 animations:^{
card.layer.transform = CATransform3DIdentity;
card.layer.opacity = 1;
}];
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
__weak typeof(self) weakSelf = self;
if (indexPath.row == [videoArray count]) {
NSLog(#"this is last cell, later make it UIActivityIndicatorView");
} else {
// RLMResults *objects;
//
// objects = [FBVideo allObjects];
// FBVideo *fbVideoRealm = objects[indexPath.row];
//
// UIImageView *imgView = (UIImageView *)[cell viewWithTag:100];
// NSURL *thumbnailImage = [NSURL URLWithString:fbVideoRealm.thumbnailsURI];
// [imgView sd_setImageWithURL:thumbnailImage placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];
//
// UILabel *titleDescription = (UILabel *)[cell viewWithTag:10];
// titleDescription.text = fbVideoRealm.titleDescription;
NSDictionary *videoData = weakSelf.videoArray[indexPath.row];
NSDictionary *videoThumbnails = [videoData valueForKey:#"thumbnails"];
NSArray *thumbnailsData = [videoThumbnails objectForKey:#"data"][0];
thumbnailsURI = [thumbnailsData valueForKey:#"uri"];
UIImageView *imgView = (UIImageView *)[cell viewWithTag:100];
NSURL *thumbnailImage = [NSURL URLWithString:thumbnailsURI];
[imgView sd_setImageWithURL:thumbnailImage placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];
UILabel *titleDescription = (UILabel *)[cell viewWithTag:10];
titleDescription.text = videoData[#"description"];
}
return cell;
}
#pragma mark <UICollectionViewDelegate>
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *videoSource = videoArray[indexPath.row];
NSURL *videoURL = [NSURL URLWithString:[videoSource valueForKey:#"source"]];
self.playerController = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[[self.playerController view] setFrame:[self.view bounds]]; // Frame must match parent view
[self.view addSubview:[self.playerController view]];
self.playerController.movieSourceType = MPMovieSourceTypeStreaming;
self.playerController.controlStyle = MPMovieControlStyleFullscreen;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doneButtonClick:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[self.playerController play];
// Play the video using AVPlayer iOS9 above
// AVPlayer *player = [AVPlayer playerWithURL:videoURL];
// AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
// playerLayer.frame = self.view.bounds;
// [self.view.layer addSublayer:playerLayer];
// [player play];
}
- (void)doneButtonClick:(NSNotification*)aNotification{
NSNumber *reason = [aNotification.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
if ([reason intValue] == MPMovieFinishReasonUserExited) {
// Your done button action here
// [self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"done button tapped");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:nil];
[self.playerController stop];
[self.playerController.view removeFromSuperview];
}
}
- (IBAction)backButtonTapped:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Helper Methods
- (void)loadVideo:(NSString*)currentPage pagesID:(NSString*)pagesID{
__weak typeof(self) weakSelf = self;
NSString *fbToken = [facebook currentFBAccessToken];
NSString *fbNextVideoURL = [NSString stringWithFormat:#"https://graph.facebook.com/v2.5/%#/videos?access_token=%#&pretty=0&fields=source,description,thumbnails.limit(1),length&limit=10&after=%#", pagesID, fbToken, currentPage];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:fbNextVideoURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *videoDict = [[NSDictionary alloc] initWithDictionary:responseObject];
if (responseObject != nil) {
[weakSelf.videoArray addObjectsFromArray:[videoDict valueForKeyPath:#"data"]];
pageBefore = [videoDict valueForKeyPath:#"paging.cursors.before"];
pageAfter = [videoDict valueForKeyPath:#"paging.cursors.after"];
// Caching pageBefore, pageAfter, thumbnailsURI, titleDescription data to REALM
for (videoInfoToSaveInRealm in weakSelf.videoArray) {
NSDictionary *videoThumbnails = [videoInfoToSaveInRealm valueForKey:#"thumbnails"];
NSArray *thumbnailsData = [videoThumbnails objectForKey:#"data"][0];
[[RLMRealm defaultRealm] transactionWithBlock:^{
[FBVideo createOrUpdateInDefaultRealmWithValue:#{#"id": self.pageID, #"titleDescription": videoInfoToSaveInRealm[#"description"], #"thumbnailsURI": [thumbnailsData valueForKey:#"uri"], #"pageBefore": pageBefore, #"pageAfter": pageAfter}];
}];
[self retrieveDataFromRealm];
}
//NSLog(#"first product's image: %#", (FBVideo *)[FBVideo allObjects]);
// Update UICollectionView UI
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self.collectionView reloadData];
});
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (void)retrieveDataFromRealm {
RLMResults *objects;
objects = [FBVideo allObjects];
FBVideo *fbVideoRealm = [[FBVideo alloc] init];
for (fbVideoRealm in objects) {
// NSLog(#"realm object count : %d", (int)objects.count);
NSLog(#"realm description : %#", fbVideoRealm.titleDescription);
NSLog(#"realm thumbnails URi : %#", fbVideoRealm.thumbnailsURI);
NSLog(#"realm page before : %#", fbVideoRealm.pageBefore);
NSLog(#"realm page after : %#", fbVideoRealm.pageAfter);
};
}
#end
Thank you in advance.
You should store the Facebook API response directly in Realm (don't display it right away), and then you can follow the pattern demonstrated in Realm's "TableView" example to back your UITableView with an RLMResults, and update the table when its data changes.
Since you'll always be loading data from the Realm this way, you get offline mode "for free".

IOS parent ViewController original coordinate missed after getting child ViewCOntroller Data

I have implemented the module to pass the values from child viewController (SliderViewController ) to master viewController (MapViewController) but when it comes to the implementation, the position just added is lost and hence the array of coordinates cannot be added and hence presented? Besides saving the coordinates into the text file and reload, are there any other alternatives to save the array of coordinates ?
The below is my working:
ChildViewCOntroller
SliderViewController.h
#import <UIKit/UIKit.h>
#import "EFCircularSlider.h"
#protocol SliderViewControllerDelegate <NSObject>
- (void)passData:(float )itemVertical : (float )itemCircular ;
#end
#interface SliderViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *uiValue;
#property (strong, nonatomic) IBOutlet UISlider *uiSlider;
#property (strong, nonatomic) IBOutlet UIButton *btnReset;
#property (strong, nonatomic) IBOutlet UILabel *uiValue2;
#property (strong, nonatomic) EFCircularSlider* circularSlider;
#property (nonatomic) float verticalSliderValue;
#property (nonatomic) float circleSliderValue;
#property (nonatomic) id <SliderViewControllerDelegate> delegate;
- (IBAction)reset:(id)sender;
- (IBAction)sliderChange:(id)sender;
- (void)buttonClicked: (id)sender;
#end
SliderViewController.m
#import "SliderViewController.h"
#import <AudioToolbox/AudioServices.h>
#import "MapViewController.h"
#interface SliderViewController (){
NSString *valueV;
NSString *valueC;
}
#end
#implementation SliderViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_uiSlider.minimumValue = 0.0;
_uiSlider.maximumValue = 100.0;
[_uiSlider removeConstraints:_uiSlider.constraints];
[_uiSlider setTranslatesAutoresizingMaskIntoConstraints:YES];
float value = M_PI * -0.5 ;
_uiSlider.transform = CGAffineTransformMakeRotation(value);
CGRect sliderFrame = CGRectMake(60, 300, 100, 100);
_circularSlider = [[EFCircularSlider alloc] initWithFrame:sliderFrame];
[_circularSlider addTarget:self action:#selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:_circularSlider];
[_circularSlider setCurrentValue:10.0f];
[_uiSlider setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.5]];
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screen);
CGFloat height = CGRectGetHeight(screen);
float scale = [[UIScreen mainScreen] scale];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake( 0, 450 ,width/2, 20);
[button setTitle:#"OK" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:16.0];
button.titleLabel.adjustsFontSizeToFitWidth = TRUE;
[button setBackgroundColor:[UIColor orangeColor]];
[button addTarget: self
action: #selector(buttonClicked:)
forControlEvents: UIControlEventTouchDown];
[self.view addSubview:button];
}
- (void) buttonClicked: (id)sender
{
NSLog( #"Button clicked." );
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)valueChanged:(EFCircularSlider*)slider {
self.uiValue2.text = [NSString stringWithFormat:#"%.02f", slider.currentValue ];
_circleSliderValue = slider.currentValue;
valueC = self.uiValue2.text;
if(slider.currentValue > 20.0 && slider.currentValue < 30.0 ){
AudioServicesPlaySystemSound(1003);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}
- (IBAction)reset:(id)sender {
[self writeToTextFile:valueV :valueC];
MapViewController * sliderVC = [self.storyboard instantiateViewControllerWithIdentifier:#"MapViewController"];
sliderVC.verticalSliderValue = _uiSlider.value;
sliderVC.circleSliderValue =_circularSlider.currentValue;
[sliderVC passData:_uiSlider.value :_circularSlider.currentValue ];
sliderVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void) writeToTextFile:(NSString*) values : (NSString*) values2 {
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/slider.txt",documentsDirectory];
NSString *content = [NSString stringWithFormat:#"%#%#%#%#", values , #"\n" , values2 , #"\n" ];
[content writeToFile:fileName
atomically:YES
encoding:NSStringEncodingConversionAllowLossy
error:nil];
NSLog(#"%#",documentsDirectory);
[self displayContent];
}
-(void) displayContent{
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/slider.txt",
documentsDirectory];
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
usedEncoding:nil
error:nil];
NSLog(#"%#",content);
}
- (IBAction)sliderChange:(id)sender {
UISlider *slider = (UISlider *)sender;
NSString *newValue = [NSString stringWithFormat:#"%.2f" , slider.value];
_verticalSliderValue = slider.value;
self.uiValue.text = newValue;
valueV = self.uiValue.text;
if(slider.value > 30 && slider.value < 50){
AudioServicesPlaySystemSound(1003);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
MasterViewController
MapViewController.h
#import <MessageUI/MessageUI.h>
#import <GoogleMaps/GoogleMaps.h>
#import <UIKit/UIKit.h>
#import "SliderViewController.h"
#interface MapViewController : UIViewController<GMSMapViewDelegate , SliderViewControllerDelegate>{
}
#property (nonatomic) float verticalSliderValue;
#property (nonatomic) float circleSliderValue;
#end
MapViewCntroller.m
#import "MapViewController.h"
#import "CheckPoints.h"
#import "NSURLRequestSSL.h"
#import "ToastView.h"
#interface MapViewController () {
GMSMapView *mapView_;
NSMutableArray *array;
GMSCameraPosition *camera;
NSArray *_styles;
NSArray *_lengths;
NSArray *_polys;
double _pos, _step;
CLLocationCoordinate2D p;
}
#end
#implementation MapViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self getTime];
array = [[NSMutableArray alloc] init];
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.uisplatch
camera = [GMSCameraPosition cameraWithLatitude:22.2855200
longitude:114.1576900
zoom:12];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.delegate = self;
mapView_.myLocationEnabled = YES;
mapView_.settings.compassButton = YES;
mapView_.settings.myLocationButton = YES;
// mapView_.delegate = self;
self.view = mapView_;
// Creates a marker in the center of the map.
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(22.2855200, 114.1576900);
marker.title = #"My place";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// defaults
float latitide = [defaults floatForKey:#"lati"];
float longitude = [defaults floatForKey:#"longi"];
NSString *desp = [defaults objectForKey:#"desp"];
if(latitide!=0.00&&longitude!=0.00) {
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(latitide, longitude);
marker.position = CLLocationCoordinate2DMake(position.latitude, position.longitude);
}
if(desp.length > 0 ){
marker.title = desp;
}
marker.snippet = #"HK";
marker.map = mapView_;
}
...
- (void)passData:(float )value1 : (float )valueCiruclar
{
NSLog(#"This was returned from ViewControllerB %ff",value1);
NSLog(#"This was returned from ViewControllerSlider %ff",valueCiruclar);
[mapView_ clear];
NSLog(#"This was map received");
CheckPoints *myCar=[[CheckPoints alloc] init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
float latitide = [defaults floatForKey:#"lati"];
float longitude = [defaults floatForKey:#"longi"];
NSString *desp = [defaults objectForKey:#"desp"];
[myCar setLatitude:latitide];
[myCar setLongitude:longitude];
[myCar setDesp:desp];
[myCar setState:[desp length] > 0 ? 0 : 1];
[CarArray addObject:myCar];
NSLog(#"This was returned lat from ViewControllerB %ff",[myCar getLatitude]);
NSLog(#"This was returned longi from ViewControllerSlider %ff",[myCar getLongitude]);
NSLog(#"This was returned desp from ViewControllerB %#",[myCar getDesp]);
NSLog(#"This was returned state from ViewControllerSlider %i",[myCar getState]);
lastChk = CarArray.lastObject;
[self writeToTextFile:[NSString stringWithFormat:#"%#%#%#%#%#%#", lastChk.getDesp , #"\n",[NSString stringWithFormat:#"%f", lastChk.getLatitude],
#"\n", [NSString stringWithFormat:#"%f", lastChk.getLongitude], #"\n" ]];
NSLog(#"This was map arraoy count #%i" , [CarArray count]);
for (int i = 0; i < [CarArray count]; i++) {
CheckPoints *current = [CarArray objectAtIndex:i];
if(current.getLatitude != lastChk.getLatitude && current.getLongitude != lastChk.getLongitude){
[current setState:1];
NSString* previousTitle = [NSString stringWithFormat:#"%#%#", #"Checkpoint" ,[NSString stringWithFormat:#"%i", i+1]];
[current setDesp:previousTitle];
}
}
[self addMarkers];
-(void) mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate{
p = coordinate;
SliderViewController * sliderVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SliderViewController"];
sliderVC.view.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0];
sliderVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:sliderVC animated:YES completion:NULL];
}
-(void) mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate
{
p = coordinate;
SliderViewController * sliderVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SliderViewController"];
sliderVC.view.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0];
sliderVC.modalPresentationStyle = UIModalPresentationCurrentContext;
**[sliderVC setDelegate:self]**
[self presentViewController:sliderVC animated:YES completion:NULL];
}
and
- (IBAction)reset:(id)sender
{
[self writeToTextFile:valueV :valueC];
[self.delegate passData:_uiSlider.value :_circularSlider.currentValue ];
[self dismissViewControllerAnimated:YES completion:nil];
}
Don't create a new instance. What you need is just use delegate.

method not being called since adding parallax image

So i recently implemented parallax images into my app which works great, however this has broken a button which calls a method.
Here is a picture of my storyboard:
http://imgur.com/uIonWrK
Here is my .h code:
#interface _01FirstViewController : UIViewController <UITextFieldDelegate, UIAccelerometerDelegate>{
UIAccelerometer *accelerometer;
float xoof;
float yoff;
float xvelocity;
float yvelocity;
float xaccel;
float yaccel;
}
#property (nonatomic, retain) UIAccelerometer *accelerometer;
#property (weak, nonatomic) IBOutlet UIScrollView *BGScrollView;
#property (weak, nonatomic) IBOutlet UIButton *Track;
#property (weak, nonatomic) IBOutlet UITextField *trackingNumber;
#property (strong, nonatomic) NSDictionary *posts;
#property (strong,nonatomic) NSString *TrackPoint;
#property (strong,nonatomic) NSArray *Path;
#property (strong,nonatomic) NSString *documentFolder;
#property (strong,nonatomic) NSString *filePath;
-(void)parseTrackNo;
-(void)reloadTrackingNumber;
Here is the relevant parts of the .m:
- (void)viewDidLoad
{
_BGScrollView.contentSize = CGSizeMake(_BGScrollView.frame.size.width+30,_BGScrollView.frame.size.width+30);
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.updateInterval = 0.03;
self.accelerometer.delegate = self;
[NSTimer scheduledTimerWithTimeInterval:-1 target:self selector:#selector(tick) userInfo:nil repeats:YES];
}
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
float xx = -acceleration.x;
float yy = (acceleration.y + 0.5f) *2.0f;
float acceldirX;
if (xvelocity * -1.0f >0){
acceldirX = 1.0;
}
else {
acceldirX = -1.0;
}
float newdirX;
if (xx > 0){
newdirX = 1.0;
}
else {
newdirX = -1.0;
}
float acceldirY;
if (yvelocity * -1.0f >0){
acceldirY = 1.0;
}
else {
acceldirY = -1.0;
}
float newDirY;
if (yy > 0){
newDirY = 1.0;
}
else {
newDirY = -1.0;
}
if (acceldirX == newdirX) xoof = acceleration.x * 30;
if (acceldirY == newDirY) yoff = acceleration.y *30;
}
This is the button that has stopped calling the method:
- (IBAction)Track:(id)sender {
[self parseTrackNo]; //Not calling method
NSLog(#"Button Pressed"); //This gets logged correctly
}
I have tried removing all code changes so i suspect it is something to do with the button being nested inside the view in the storyboard or the delegate changes.
Can anyone point me in the correct direction?
EDIT as requested the code for parseTrackingNo (note this was working perfectly until the parallax changes):
-(void)parseTrackNo
{
_01AppDelegate *appDelegate = (_01AppDelegate *)[[UIApplication sharedApplication] delegate];
//Get Tracking Number from textField
appDelegate.TrackingNumber = _trackingNumber.text;
//Check String isn't empty
if ([_trackingNumber.text isEqual: #""]){
} else{
//Check against Royal Mail API
NSString *trackingURL = [NSString stringWithFormat:#"%#%#", #"http://api.e44.co/tracktrace/", appDelegate.TrackingNumber];
NSURL *royalMail = [NSURL URLWithString:trackingURL];
//Return results
NSData *royalMailResults = [NSData dataWithContentsOfURL:royalMail];
//Parse JSON results
if(royalMailResults != nil)
{
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:royalMailResults options:NSJSONReadingMutableContainers error:&error];
if (error == nil)
//Convert to dictionary/array
self.posts = (NSDictionary *)result;
NSArray *trackRecords = _posts[#"trackRecords"];
//Return keys from posts (Dict)
NSString *response = [self.posts valueForKeyPath:#"response"];
NSLog(#"Response: %#", response);
NSString *returnedTrackingNumber = [self.posts valueForKeyPath:#"trackingNumber"];
NSLog(#"Returned tracking number: %#", returnedTrackingNumber);
NSString *delivered = [self.posts valueForKeyPath:#"delivered"];
NSLog(#"delivered: %#", delivered);
NSString *signature = [self.posts valueForKeyPath:#"signature"];
NSLog(#"Signature: %#", signature);
//Track Records
NSString *Date = [trackRecords valueForKeyPath:#"date"];
NSLog(#"date: %#", Date);
NSString *Time = [trackRecords valueForKeyPath:#"time"];
NSLog(#"time: %#", Time);
NSString *Status = [trackRecords valueForKeyPath:#"status"];
NSLog(#"status: %#", Status);
appDelegate.LocationData = [[trackRecords valueForKey:#"trackPoint"] componentsJoinedByString:#""];
NSLog(#"GeoLocation: %#", appDelegate.LocationData);
//Check for Errors returned
if ([self.posts objectForKey:#"errorMsg"]) {
NSLog(#"ERROR MOTHERFUCKER");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"It appears that you have entered an incorrect tracking number"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alert show];
} else {
[self performSegueWithIdentifier:#"addPackageSegue" sender:self];
}
}
}
}

Xcode button linking error?

Hey I was wondering is their any possible way I can link two actions to the same button in Xcode? I've already tried but keep getting this error: "terminating with uncaught exception of type NSException". So i'm guessing I am not able to do that? See what i'm trying to do is
make a button play a sound but that same button is also linked to starting a new round in the game. How would I go about doing this? I've currently got this going in my .m file.
#import "BullsEyeViewController.h"
#interface BullsEyeViewController ()
#end
#implementation BullsEyeViewController
{
int _currentValue;
int _targetValue;
int _score;
int _round;
}
- (IBAction)playSound:(id)sender {
SystemSoundID soundID;
NSString *buttonName=[sender currentTitle];
NSString *soundFile=[[NSBundle mainBundle]
pathForResource:buttonName ofType:#"mp3"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)
[NSURL fileURLWithPath:soundFile], &
soundID);
AudioServicesPlaySystemSound(soundID);
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self startNewGame];
[self updateLabels];
UIImage *thumbImageNormal = [UIImage
imageNamed:#"SliderThumb-Normal"];
[self.slider setThumbImage:thumbImageNormal
forState:UIControlStateNormal];
UIImage *thumbImageHighlighted = [UIImage
imageNamed:#"SliderThumb-Highlighted"];
[self.slider setThumbImage:thumbImageHighlighted
forState:UIControlStateHighlighted];
UIImage *trackLeftImage =
[[UIImage imageNamed:#"SliderTrackLeft"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 14, 0, 14)];
[self.slider setMinimumTrackImage:trackLeftImage
forState:UIControlStateNormal];
UIImage *trackRightImage =
[[UIImage imageNamed:#"SliderTrackRight"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 14, 0, 14)];
[self.slider setMaximumTrackImage:trackRightImage
forState:UIControlStateNormal];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)startNewRound
{
_round += 1;
_targetValue = 1 + arc4random_uniform(100);
_currentValue = 50;
self.slider.value = _currentValue;
}
- (void)startNewGame
{
_score = 0;
_round = 0;
[self startNewRound];
}
- (void)updateLabels
{
self.targetLabel.text = [NSString stringWithFormat:#"%d",
_targetValue];
self.scoreLabel.text = [NSString stringWithFormat:#"%d",
_score];
self.roundLabel.text = [NSString stringWithFormat:#"%d",
_round];
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)showAlert
{
int difference = abs(_targetValue - _currentValue);
int points = 100 - difference;
NSString *title;
if (difference == 0) {
title = #"Perfect!";
points += 100;
} else if (difference < 5) {
title = #"You almost had it!";
if (difference == 1) {
points += 50;
}
} else if (difference < 10 ) {
title = #"Pretty good!";
} else {
title = #"Not even close...";
}
_score+=points;
NSString *message = [NSString stringWithFormat:#"You scored %d points", points];
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
}
-(IBAction)sliderMoved:(UISlider *)slider
{
_currentValue = lroundf(slider.value);
}
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startNewRound];
[self updateLabels];
}
-(IBAction)startOver
{
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseOut];
[self startNewGame];
[self updateLabels];
[self.view.layer addAnimation:transition forKey:nil];
}
#end
And here's my .h file.
//
// BullsEyeViewController.h
// BullsEye
//
// Created by Sebastian Shelley on 28/04/2014.
// Copyright (c) 2014 Sebastian Shelley. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface BullsEyeViewController : UIViewController
<UIAlertViewDelegate>
#property (nonatomic, weak) IBOutlet UISlider *slider;
#property (nonatomic, weak) IBOutlet UILabel *targetLabel;
#property (nonatomic, weak) IBOutlet UILabel *scoreLabel;
#property (nonatomic, weak) IBOutlet UILabel *roundLabel;
-(IBAction)showAlert;
-(IBAction)sliderMoved:(UISlider *)slider;
-(IBAction)startOver;
- (IBAction)playSound:(id)sender;
#end
Some help would be greatly appreciated :)
Add an action like this to the button
-(IBAction)myButtonPressed:(id)sender
{
[self playSound:sender];
[self startNewRound:Sender];
}
Use only one action, just set a BOOL to check if you need to play the sound or not.
Example code would be:
-(IBAiction)btnPressed:(id)sender
{
if(playsound)
{
[self playSound];
playsound = NO;
}
[self startOver];
}
And then whenever you want the saund to be played again just set playsound to YES and next time user presses the button it will play the sound again

Custom UIButton(CheckBox) add responder to action iOS SDK

I have custom UIButton class:
CheckBox.h
#interface CheckBox : UIButton {
BOOL isChecked;
IBOutlet UIWebView *webview;
IBOutlet UIImageView *img;
NSMutableString *labelText;
NSInteger fontSize;
NSInteger heightWebView;
}
#property (nonatomic,retain) NSMutableString *labelText;
#property (nonatomic,retain) UIImageView *img;
#property (nonatomic,retain) UIWebView *webview;
#property (nonatomic,assign) BOOL isChecked;
-(IBAction) checkBoxClicked;
-(void)addText:(NSString *) text redLetter:(NSInteger)redLetter isBold:(NSInteger)
isBold;
-(BOOL)getStatus;
-(NSString*)getText;
-(void)setFontSize:(NSInteger)setFontSizeValue;
#end
CheckBox.m look on IBAction i need implement functionality there
#import "CheckBox.h"
#implementation CheckBox
#synthesize isChecked, webview, img, labelText, delegate;
- (id)initWithFrame:(CGRect)frame {
if (self == [super initWithFrame:frame]) {
// Initialization code
fontSize = 2;
self.isChecked = NO;
self.labelText = [[NSMutableString alloc] init];
self.contentHorizontalAlignment =
UIControlContentHorizontalAlignmentLeft;
img = [[UIImageView alloc] initWithFrame:CGRectZero];
img.image = [UIImage imageNamed:#"checkbox.png"];
[self addSubview:img];
webview = [[UIWebView alloc] initWithFrame:frame];
webview.backgroundColor = [UIColor clearColor];
[webview setOpaque:NO];
webview.userInteractionEnabled = NO;
[self addSubview:webview];
/* [self setImage:[UIImage imageNamed:
#"checkbox.png"]
forState:UIControlStateNormal];*/
[self addTarget:self action:
#selector(checkBoxClicked)
forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
-(IBAction) checkBoxClicked{
if(self.isChecked ==NO){
self.isChecked =YES;
img.image = [UIImage imageNamed:#"checkbox-checked.png"];
}else{
self.isChecked =NO;
img.image = [UIImage imageNamed:#"checkbox.png"];
}
}
-(BOOL)getStatus{
return self.isChecked;
}
-(NSString*)getText{
return [NSString stringWithFormat:#"%#",self.labelText];
}
-(void)setFontSize:(NSInteger)setFontSizeValue {
fontSize = setFontSizeValue;
if (fontSize >2) {
heightWebView = fontSize+2;
}
}
-(void)addText:(NSString *) text redLetter:(NSInteger)redLetter isBold:(NSInteger)isBold
{
[self.labelText setString:text];
if (redLetter != 0) {
NSString *first;
NSString *red;
NSString *second;
first = [text substringWithRange:NSMakeRange(0, redLetter-1)];
red = [text substringWithRange:NSMakeRange(redLetter-1, 1)];
second = [text substringWithRange:NSMakeRange(redLetter, [text length] - redLetter )];
if(isBold == 0) {
NSString *html = [NSString stringWithFormat:#"<font size=\"%d\"><p>%#<span style=\"color:red;\">%#</span>%#</p></font>",fontSize, first,red,second];
[webview loadHTMLString:html baseURL:nil];
}else{
NSString *html = [NSString stringWithFormat:#"<font size=\"%d\"><p>%#<span style=\"color:red;\">%#</span>%#</p></font>",fontSize, first,red,second];
[webview loadHTMLString:html baseURL:nil];
}
}else {
if(isBold == 0) {
NSString *html = [NSString stringWithFormat:#"<font size=\"%d\"><p>%#</p></font>",fontSize, text];
[webview loadHTMLString:html baseURL:nil];
}else{
NSString *html = [NSString stringWithFormat:#"<font size=\"%d\"><p>%#</p></font>",fontSize, text];
[webview loadHTMLString:html baseURL:nil];
}
}
}
- (void)layoutSubviews {
img.frame = CGRectMake(0, 5, 18 , 18);
webview.frame = CGRectMake(12, 0-heightWebView, self.bounds.size.width- 11 , 25+heightWebView);
}
- (void)dealloc {
[webview release];
[img release];
[super dealloc];
}
#end
I need to add functionality to this class, that when user click on button in class where i implement CheckBox class will call some void.
Let me explain better i want to implement here functionality like in UIAlertView where you click on button calls
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
I need something like
- (void)checkBox:(CheckBox *)checkBox didStatusChanged:(BOOL)checkBoxStatus
Sounds like you want to implement a delegate protocol. This would go at the top of checkbox.h above your #interface
#protocol CheckBoxDelegate
#optional
- (void)checkBox:(CheckBox *)checkBox didStatusChanged:(BOOL)checkBoxStatus;
#end
You'd then want to add this to your checkbox.h #interface
#property (monatomic, assign) NSObject <CheckBoxDelegate> delegate;
You could then implement the
checkBox:(CheckBox *)checkBox didStatusChanged:(BOOL)checkBoxStatus
function in your ViewController or whatever is creating the checkboxes, and for each checkbox do
[checkbox setDelegate:self];
Then inside -(IBAction) checkBoxClicked you can call
[delegate checkBox:self didStatusChanged:self.isChecked];
and this would call that method on the class spawning the checkboxes/delegate.
Hope this is extensive enough.
Tim

Resources