I am experimenting this issue while trying to open a webpage in an ios app. Before ios7 it was working perfect but now we are upgrading our app and this is the only serious problem we have.
About this problem I found that it is produced when a call is made twice. And I think this is what is happening here because if I write a NSLog text in didFailLoadWithError, it shows twice.
I tried ignoring the error but the loading circle is shown ethernally and webpage not loads.
I paste here my code, maybe you can help us or give us a clue.
#import "WebPoiViewController.h"
#import "FavoriteManager.h"
#interface WebPoiViewController ()
#end
#implementation WebPoiViewController
#synthesize webView,urlStr, activityIndicator,title2,poi=_poi,position=_position;
- (void)viewDidLoad { //We have a NIB file in play here, so I dropped the loadView here. Just make sure that your loadView is not getting called twice!
[super viewDidLoad];
if (self.poi!=nil){
self.position = [[FavoriteManager sharedInstance] isPoiInFavoriteList:self.poi];
if (self.position==-1){
UIButton *button1 = [[UIButton alloc] init];
button1.frame=CGRectMake(0,0,30,30);
[button1 setBackgroundImage:[UIImage imageNamed: #"Favorites_icon_inactive.png"] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(makeFavorite:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:button1];
//self.navigationItem.rightBarButtonItem= [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"Favorites_icon_inactive.png"] style: UIBarButtonItemStylePlain target:self action:#selector(makeFavorite:)];
} else {
UIButton *button1 = [[UIButton alloc] init];
button1.frame=CGRectMake(0,0,30,30);
[button1 setBackgroundImage:[UIImage imageNamed: #"Favorites_icon.png"] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(deleteFavorite:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:button1];
//self.navigationItem.rightBarButtonItem= [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"Favorites_icon.png"] style: UIBarButtonItemStylePlain target:self action:#selector(deleteFavorite:)];
}
}
if (nil!=title2&& ![title2 isEqualToString:#""]){
self.title=self.title2;
}
[self loadView];
}
- (IBAction)makeFavorite:(id)sender {
self.position=[[FavoriteManager sharedInstance] addFavotitePOI:self.poi];
UIButton *button1 = [[UIButton alloc] init];
button1.frame=CGRectMake(0,0,30,30);
[button1 setBackgroundImage:[UIImage imageNamed: #"Favorites_icon.png"] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(deleteFavorite:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:button1];
}
- (IBAction)deleteFavorite:(id)sender {
[[FavoriteManager sharedInstance] deleteFavotitePOIat:self.position];
self.position=-1;
UIButton *button1 = [[UIButton alloc] init];
button1.frame=CGRectMake(0,0,30,30);
[button1 setBackgroundImage:[UIImage imageNamed: #"Favorites_icon_inactive.png"] forState:UIControlStateNormal];
[button1 addTarget:self action:#selector(makeFavorite:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:button1];
}
- (void)loadView {
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = contentView;
CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
webFrame.origin.y = 0.0f;
webView = [[UIWebView alloc] initWithFrame:webFrame];
webView.backgroundColor = [UIColor blueColor];
webView.scalesPageToFit = YES;
webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
webView.delegate = self;
if([webView respondsToSelector:#selector(scrollView)]){
webView.scrollView.bounces = NO;
}
[self.view addSubview: webView];
if (nil!=self.urlStr && ![urlStr isEqualToString:#""]){
NSLog(#"NO ES NIL");
//[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlStr]]];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]];
activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
//activityIndicator.center = self.view.center;
activityIndicator.center = CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2);
[self.view addSubview: activityIndicator];
} else{
[webView loadHTMLString:#"<html><center><br /><br /><font size=+5>No info<br /><br /></font></center></html>" baseURL:nil];
}
}
#pragma mark WEBVIEW Methods
- (void)webViewDidStartLoad:(UIWebView *)myWebView
{
// starting the load, show the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[activityIndicator startAnimating];
}
- (void)webViewDidFinishLoad:(UIWebView *)myWebView
{
// finished loading, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[activityIndicator stopAnimating];
}
- (void)webView:(UIWebView *)myWebView didFailLoadWithError:(NSError *)error
{
if([error code] == NSURLErrorCancelled) return; // Ignore this error
NSLog(#"FAIL");
// load error, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// report the error inside the webview
NSString* errorString = [NSString stringWithFormat:
#"<html><center><br /><br /><font size=+5 color='red'>Error<br /><br />Your request %#</font></center></html>",
error.localizedDescription];
[webView loadHTMLString:errorString baseURL:nil];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
- (BOOL)shouldAutorotate {
return [self.navigationController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.navigationController supportedInterfaceOrientations];
}
#end
I solved it by myself. I want to share the answer because maybe it helps others with the same problem.
I just added in didFailWithError this code:
- (void)webView:(UIWebView *)myWebView didFailLoadWithError:(NSError *)error
{
if([error code] != NSURLErrorCancelled) // only goes in if it is not -999
{
// load error, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// report the error inside the webview
NSString* errorString = [NSString stringWithFormat:
#"<html><center><br /><br /><font size=+5 color='red'>Error<br /><br />Your request %#</font></center></html>",
error.localizedDescription];
[webView loadHTMLString:errorString baseURL:nil];
}
else{
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlStr] ]];
}
}
Now, if it fail, it tries to repeat the load until it loads. It can be improved by using a counter. Just trying it 5 or 10 times and not more like mine.
Related
I have an issue, when the view is loaded, it will load the UIBarButtonItem, but then i have to set it to nil in "mostra_filtro_btn", but then again in "load_map" i have to set it, but it doesn't show up.
Here is my code:
//
// FirstViewController.m
// House Finder
//
// Created by Giovanni Poli on 12/05/15.
// Copyright (c) 2015 Giovanni Poli. All rights reserved.
//
#import "MapViewController.h"
#import <QuartzCore/QuartzCore.h>
#import "Reachability.h"
#import "UIKit/UIKit.h"
#import <Foundation/Foundation.h>
#import "FiltroViewController.h"
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize filtro_controller,overlay_filtro_counter,mappa_controller;
-(void)load_map{
NSLog(#"load_map");
[mapView removeFromSuperview];
[mappa_controller.view removeFromSuperview];
[filtro_controller.view removeFromSuperview];
UIBarButtonItem *Button = [[UIBarButtonItem alloc] initWithTitle:#"Filtro" style:UIBarButtonItemStyleBordered target:self action:#selector(mostra_filtro_btn:)];
[Button setTitle:#"Filtro"];
[Button setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName,nil]forState:UIControlStateNormal];
self.navigationItem.rightBarButtonItem = Button;
}
- (id) init{
filtro_controller = [[FiltroViewController alloc]init];
[self.view addSubview:filtro_controller.view];
[self addChildViewController:filtro_controller];
return self;
}
- (void)viewDidLoad {
self.title = #"Mappa";
self.navigationItem.title = #"House Finder";
self.navigationController.navigationBar.translucent = FALSE;
UIBarButtonItem *Button = [[UIBarButtonItem alloc] initWithTitle:#"Filtro" style:UIBarButtonItemStyleBordered target:self action:#selector(mostra_filtro_btn:)];
[Button setTitle:#"Filtro"];
[Button setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName,nil]forState:UIControlStateNormal];
self.navigationItem.rightBarButtonItem = Button;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"json"];
NSData *content = [[NSData alloc] initWithContentsOfFile:filePath];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:content options:kNilOptions error:nil];
NSArray * json_all = [json objectForKey:#"results"];
mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height-40)];
mapView.delegate = self;
mapView.showsUserLocation = NO;
mapView.userInteractionEnabled = YES;
CLLocationCoordinate2D annotationCoord;
self.view.userInteractionEnabled = YES;
NSDictionary * temp;
for (id object in json_all) {
temp = object[#"titolo"];
annotationCoord.latitude = [object[#"lat"] floatValue];
annotationCoord.longitude = [object[#"lon"] floatValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = object[#"titolo"];
annotationPoint.subtitle = object[#"agenzia"];
[mapView addAnnotation:annotationPoint];
}
[mapView showAnnotations:[mapView annotations] animated:YES];
[self.view addSubview:mapView];
[self.view setNeedsDisplay];
}
- (IBAction) mostra_filtro_btn: (id)sender{
NSLog(#"mostra_filtro_btn");
self.navigationItem.rightBarButtonItem = nil;
filtro_controller = [[FiltroViewController alloc]init];
[self.view addSubview:filtro_controller.view];
[self addChildViewController:filtro_controller];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapViews viewForAnnotation:annotation{
if (annotation == mapViews.userLocation) return nil;
MKPointAnnotation * temp = annotation;
MKAnnotationView * m = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"casa"];
m.canShowCallout = YES;
m.enabled = YES;
m.userInteractionEnabled = YES;
NSString * icon_file = [NSString stringWithFormat:#"%#.png",temp.subtitle];
m.image = [UIImage imageNamed:icon_file];
return m;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
NSLog(#"overlay prezzo");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Use the following code to nil the navigation item so it will hide where ever you want
[self.navItem setRightBarButtonItem:nil];
[self.navItem setLeftBarButtonItem:nil];
Try first create the UIButton then put it into the navigation button as follow
UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 44.0f, 30.0f)];
[backButton setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(popVC) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
Since I can't post this as a comment here is what I think is missing inside load_map:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"load_map");
[mapView removeFromSuperview];
[mappa_controller.view removeFromSuperview];
[filtro_controller.view removeFromSuperview];
UIBarButtonItem *Button = [[UIBarButtonItem alloc] initWithTitle:#"Filtro" style:UIBarButtonItemStyleBordered target:self action:#selector(mostra_filtro_btn:)];
[Button setTitle:#"Filtro"];
[Button setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName,nil]forState:UIControlStateNormal];
self.navigationItem.rightBarButtonItem = Button;
})
This is a possible solution till you try it. If you share the code from where you call load_map it would be great!
Cheers!
Your code works perfect, as you said you are adding button with method mostra_filtro_btn : in viewDidLoad method, and on click of button, button from navigation bar set to nil.
But the problem is that, from nowhere you calls load_map method. You need to call this method once the button gets nil, to get it back with load_map method.
May you get it.
Enjoy Coding!!
I am developing iOS App with Objective-c. Then, I am implementing customized Activity Indicator which is active while webView is loading.
The customized Activity Indicator appears when webView starts loading, however it does not disappear when webView finishes loading.
My code is following.
Could you tell me how to solve this problem?
#interface DetailViewController ()<UIWebViewDelegate>{
{
UILabel *loadingLabel;
UIActivityIndicatorView *loadingMark;
UIView *loadingContainer;
}
#property (weak, nonatomic) IBOutlet UIWebView *detailPage;
#end
#implementation DetailViewController
- (void)configureView
{
NSURL *page_url = [NSURL URLWithString:#"http://yahoo.co.jp"];
NSURLRequest *request = [NSURLRequest requestWithURL:page_url];
[_detailPage loadRequest:request];
_detailPage.delegate = self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)webViewDidStartLoad:(UIWebView*)webView
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self animatingIndicator];
}
- (void)webViewDidFinishLoad:(UIWebView*)webView
{
[self stopAndRemoveIndicator];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
-(void)animatingIndicator {
loadingContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 60)];
//Set Style Of Label
loadingLabel = [[UILabel alloc] init];
loadingLabel.text = #"Loading";
loadingLabel.textColor = [UIColor whiteColor];
loadingLabel.shadowColor = [UIColor blackColor];
loadingLabel.shadowOffset = CGSizeMake(1, 1);
loadingLabel.font = [UIFont boldSystemFontOfSize:17];
loadingLabel.backgroundColor = [UIColor lightGrayColor];
loadingLabel.frame = CGRectMake(20, 17, 70, 25);
[loadingContainer addSubview:loadingLabel];
//Set Style Of Mark
loadingMark = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
loadingMark.frame = CGRectMake(100, 14, 30, 30);
[loadingContainer addSubview:loadingMark];
//Set Style Of Container
loadingContainer.backgroundColor = [UIColor lightGrayColor];
[[loadingContainer layer] setCornerRadius:8.0f];
[[loadingContainer layer] setMasksToBounds:YES];
[[loadingContainer layer] setBorderWidth:0.5f];
[[loadingContainer layer] setBorderColor:[[UIColor darkGrayColor] CGColor]];
CGRect rect = self.view.frame;
loadingContainer.center = CGPointMake(rect.size.width/2, rect.size.height/2 * 0.8);
[self.view addSubview:loadingContainer];
[loadingMark startAnimating];
loadingContainer.hidden = NO;
}
-(void)stopAndRemoveIndicator {
[loadingMark stopAnimating];
loadingContainer.hidden = YES;
[loadingMark setHidden:YES];
}
You need to hide the UIKit objects in the main thread.
override func webViewDidFinishLoad(webView:UIWebView)
{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.loadingSign.stopAnimating()
self.loadingSign.hidden = true
}
}
Update for swift 4
override func webViewDidFinishLoad(_ webView: UIWebView)
{
DispatchQueue.main.async {
self.loadingSign.stopAnimating()
self.loadingSign.hidden = true
}
}
loadingSign is UIActivity Indicator.
This is what I have done, work fine!
.h file
#property (retain, nonatomic) IBOutlet UIActivityIndicatorView *loadingSign;
.m file
-(void)webViewDidStartLoad:(UIWebView *)webView
{
[self.loadingSign startAnimating];
self.loadingSign.hidden = NO;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[self.loadingSign stopAnimating];
self.loadingSign.hidden = YES;
}
I have a parent->child navigation setup in application. I use navigation via pushViewController function.
-(void)loadMemosViewController:(id)sender{
if(activeHullGuid != nil && activeHullGuid.length > 0)
{
NSString *storyboardName = #"MainStoryboard_iPhone1";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
MemosViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:#"sid_Memos"];
loginVC.keyReference = [[KeyValuePairIS alloc] initWithData:&controllerID:activeHullGuid];
[self.navigationController pushViewController:loginVC animated:YES];
}
}
for back navigation I use only default implementation in IOS (that would be a click on a back button).
This setup works for most situations, but recent implementation is causing problems.
The problem is this:
I have parent view controller named "hullViewController" and a child "memosViewController". The navigation between them works. Child does not report any information back to parent. HullViewController is also an editable form, which changes edit state via button in navigation bar.
Now if I change this edit/read state on hullViewController works nonstop. If I visit the child memosViewController, and go back to parent, I can only change state once more, then application crashes with exc_bad_access code=1.
After profiling with "Zombies" I found the culprit for exception is my probably disposed child memosViewController.
An Objective-C message was sent to a deallocated 'MemosViewController' object (zombie) at address: 0xdd52f10
it seams to crash on an IOS internal event, since none of my breakpoints are hit before crash.
A you can see the child is instanced during creation and I don't reference it to nothing else. Why would the edit state change request the child object?
What I tried already:
-declaring MemosViewController as a class variable. (application did not crash anymore, but would not change state anymore).
-initialising MemosViewController on viewDidLoad, changed nothing.
-calling child with class init only (not via storyboard), loaded child without UI, but result was same.
Project is set up with ARC, so I have minimum control on disposal of objects.
I have been searching for a solution quite a while now, with no results. Any help to solve my error editing if I visit the child would be appreciated.
UPDATE
I have additionally discovered, that when I get back to parent from child, the reference self.navigationItem still points to child, and any update to navigation buttons crashes the app.
**attaching custom ViewController, since it could be related to problem **
#import "UITableViewControllerEx.h"
#import "UITextFieldEx.h"
#import "UITextViewEx.h"
#import "GlobalValues.h"
#import "UITableViewEx.h"
#interface UITableViewControllerEx ()
#end
#implementation UITableViewControllerEx
UIBarButtonItem *bbi_navigateToMaster;
UIBarButtonItem *editButton;
UIButton *cmdEdit;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self setNavigationBackground];
[self setApplicationTintColor];
[self setApplicationTitleFont];
[self setupLeftBarButtonItem];
[self setBackButton];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//UITextFieldEx delegate to control the length of fields
- (BOOL)textField:(UITextFieldEx *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > textField.maxLength) ? NO : YES;
}
//UITextViewEx delegate to control the length of fields
-(BOOL)textView:(UITextViewEx *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
NSUInteger newLength = [textView.text length] + [text length] - range.length;
return (newLength > textView.maxLength) ? NO : YES;
}
//function to set left button to always pop to root controller
- (void)setBackButtonToReturnToMaster {
UIButton *cmdHome = [[UIButton alloc] initWithFrame:CGRectMake(0,0,30,30)];
[cmdHome setImage:[UIImage imageNamed:#"home"] forState:UIControlStateNormal];
bbi_navigateToMaster = [[UIBarButtonItem alloc] initWithCustomView:cmdHome];
[cmdHome addTarget:self action:#selector(backToMaster:) forControlEvents:UIControlEventTouchUpInside ];
self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:bbi_navigateToMaster , nil];
/*
bbi_navigateToMaster = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:self action:#selector(backToMaster:)];
self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:bbi_navigateToMaster , nil];
[bbi_navigateToMaster setImage:[UIImage imageNamed:#"home"]];
[bbi_navigateToMaster setImageInsets:UIEdgeInsetsMake(2, 2, 2, 2)];*/
}
//pop to root controller
-(void)backToMaster:(id)sender {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
}
else { [self.navigationController popToRootViewControllerAnimated:YES]; }
}
//find superview element of given type
- (UIView *)findSuperViewWithClass:(Class)superViewClass uiViewToSearch:(UIView*)bottomView{
UIView *superView = bottomView.superview;
UIView *foundSuperView = nil;
while (nil != superView && nil == foundSuperView) {
if ([superView isKindOfClass:superViewClass]) {
foundSuperView = superView;
break;
} else {
superView = superView.superview;
}
}
return foundSuperView;
}
-(void)setNavigationBackground{
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
UIImage *image = [UIImage imageNamed:#"navigationBackground"];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
UIView* uv = [[UIView alloc] initWithFrame:CGRectMake(0, self.navigationController.navigationBar.frame.size.height-1,self.navigationController.navigationBar.frame.size.width, 1)];
[uv setBackgroundColor:[GlobalValues getTintColor]];
[self.navigationController.navigationBar insertSubview:uv atIndex:10];
}
}
//sets the tint color of szstem items (title, szstem buttons, ...)
-(void)setApplicationTintColor {
NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ([[ver objectAtIndex:0] intValue] >= 7) {
self.navigationController.navigationBar.barTintColor = [GlobalValues getTintColor];
self.navigationController.navigationBar.tintColor = [GlobalValues getTintColor];
self.navigationController.navigationBar.translucent = NO;
[self.navigationController.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
UIColor *color = [GlobalValues getTintColor];
self.view.tintColor = color;
}else {
//self.navigationController.navigationBar.tintColor = [GlobalValues getTintColor];
/*NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil];
[[UINavigationBar appearance] setTitleTextAttributes:textTitleOptions];*/
}
}
//sets the navigation title
-(void)setApplicationTitleFont {
NSArray *ver = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ([[ver objectAtIndex:0] intValue] >= 7) {
[self.navigationController.navigationBar setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"HelveticaNeue-Light" size:21],
NSFontAttributeName, [UIColor whiteColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil]];
}else {
[self.navigationController.navigationBar setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeFont: [UIFont fontWithName:#"Helvetica-Light" size:21.0f]
}];
}
}
-(void)setupLeftBarButtonItem{
cmdEdit = [[UIButton alloc] initWithFrame:CGRectMake(0,0,30,30)];
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
editButton = [[UIBarButtonItem alloc] initWithCustomView:cmdEdit];
[cmdEdit addTarget:self action:#selector(setEditState) forControlEvents:UIControlEventTouchUpInside];
}
- (UIBarButtonItem *)leftBarButtonItem
{
if (self.tableView.editing) {
[cmdEdit setImage:[UIImage imageNamed:#"unlocked"] forState:UIControlStateNormal];
return editButton;
}
else {
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
return editButton;
}
}
-(void)updateEditButton{
if (self.tableView.editing) {
[cmdEdit setImage:[UIImage imageNamed:#"unlocked"] forState:UIControlStateNormal];
}
else {
[cmdEdit setImage:[UIImage imageNamed:#"locked"] forState:UIControlStateNormal];
}
}
-(void)setEditState{
if (!self.tableView.editing) {
[self setEditing:YES animated:YES];
} else {
[self setEditing:NO animated:YES];
}
[self updateEditButton];
}
}*/
-(void) setBackButton{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"back"] ;
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(goback) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 30, 30);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;
self.navigationItem.leftBarButtonItem = backButton;
}
- (void)goback
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - Table view data source
#pragma mark - Table view delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.backgroundView=[[UIView alloc] initWithFrame:CGRectZero];
cell.backgroundColor = [UIColor clearColor];
cell.layer.backgroundColor = [UIColor clearColor].CGColor;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *customTitleView = [ [UIView alloc] initWithFrame:CGRectMake(10, 0, 300, 44)];
UIView *customTitleLineView = [ [UIView alloc] initWithFrame:CGRectMake(10, 43, self.view.frame.size.width -20, 0.5f)];
customTitleLineView.backgroundColor = [GlobalValues getTintColor];
UILabel *titleLabel = [ [UILabel alloc] initWithFrame:CGRectMake(20, 0, 300, 44)];
titleLabel.text = [self tableView:tableView titleForHeaderInSection:section];
titleLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:18];
titleLabel.textColor = [GlobalValues getTintColor];
titleLabel.backgroundColor = [UIColor clearColor];
if (titleLabel.text.length != 0) {
[customTitleView addSubview:customTitleLineView];
}
[customTitleView addSubview:titleLabel];
return customTitleView;
}
#end
Seems I have found a solution to my problem.
Class UITableViewControllerEx contains functionality to setup edit button. The class variable "UIBarButtonItem *editButton;" is then used as edit button on all forms that inherit from "UITableViewControllerEx"
the solution was to instantiate UIBarButtonItem on each form inheriting UITableViewControllerEx with local name (like editButtonHull) and given as param to logic of superclass.
Thanks to #akashg for suggestion that Navigation bar modification might be the problem
I have many view controller when i click on tableView cell it move to new view controller problem is that it takes alot of time to move to the next view may be due to view which is to load fetches data from server here is my code for the view which loads
- (void)viewDidLoad {
appDelegate = (MultipleDetailViewsWithNavigatorAppDelegate *)[[UIApplication sharedApplication] delegate];
UIImageView *bottomImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Nav.png"]];
[bottomImageView setFrame:CGRectMake(0,690,1024,34)];
[self.view addSubview:bottomImageView];
UIButton *button1=[UIButton buttonWithType:UIButtonTypeCustom];
[button1 setFrame:CGRectMake(10.0, 2.0, 88, 40.0)];
[button1 addTarget:self action:#selector(loginPressed) forControlEvents:UIControlEventTouchUpInside];
[button1 setImage:[UIImage imageNamed:#"logoutN.png"] forState:UIControlStateNormal];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithCustomView:button1];
self.navigationItem.rightBarButtonItem = button;
self.title=#"Catalog";
popImageView.hidden=YES;
passwordLabel.hidden=YES;
userLabel.hidden=YES;
userNameTextField.hidden=YES;
userPasswordTextField.hidden=YES;
signInButton.hidden=YES;
tableView.hidden=NO;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
if(!categoryArray){
categoryArray =[[NSMutableArray alloc] init];
}
if(!userArray){
userArray =[[NSMutableArray alloc] init];
}
if(!subCategoryArray){
subCategoryArray =[[NSMutableArray alloc] init];
}
if(!subCategoryArrayOne){
subCategoryArrayOne =[[NSMutableArray alloc] init];
}
if(!subCategoryArrayTwo){
subCategoryArrayTwo =[[NSMutableArray alloc] init];
}
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
int count=[appDelegate.coffeeArray count];
NSLog(#"Arrays Content Are %d",count);
tableView.backgroundView = nil;
[super viewDidLoad];
}
is there any way so that view loads fast
Your view is not loading fast because of I guess those data set operation in viewDidLoad method . I think those are :
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
The one thing you could do is to move this operations to perform on the background thread . For that move this operations to the separate function and call that to perform on background from the view did load method :
-(void)dataOperations
{
[self setUpData];
[self setUpDataSub];
[self setUpDataSubOne];
[self setUpDataSubTwo];
}
and in viewDidLoad call this function in background:
[self performSelectorInBackground:#selector(dataOperations) withObject:nil];
Or you can directly call those method from viewDidLoad like :
[self performSelectorInBackground:#selector(setUpData) withObject:nil];
Let me first state, that this is not a matter of getting my selector name right, nor setting up the button target in loadView, nor any other suggestion I've seen in the last 4 hours of browsing. I should also explain I am not using nibs, nor IB.
These buttons have been working for the bulk of development.
Then poof! It's not just the buttons. My table views do not scroll. Pressing the cells in the table views do not invoke the actions that I had setup.
It seems I've broken the responder chain entirely; or something to that effect.
To try and narrow down the source of the problem a created a window-based project; stripped out everything that xCode generates; deleted the nib; and copied in several methods from my original app delegate and my rootViewController.
It's the RVT that contains the subView that contains the buttons. Fairly straight forward. Same effect. I've literally stripped out all functional code but the following source in appDelegate.m:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setDelegate:self];
if(window == nil)
window = [[UIWindow alloc] init];
window.autoresizesSubviews = YES;
if(controller == nil)
controller = [[Controller alloc] init];
window.rootViewController = controller;
[window makeKeyAndVisible];
return YES;
}
-(void)dealloc {
[window release];
[controller release];
[super dealloc];
}
And in Controller:
- (void)buttonResponse {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
[super loadView];
//test
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse) forControlEvents: UIControlEventTouchUpInside];
UIView *view = self.view;
CGRect viewFrame = view.frame; //self.view is valid and takes up available screen
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
//end test
[self.view setNeedsDisplay];
}
- (void)dealloc {
[button release];
[super dealloc];
}
I know it's gotta be something really simple. But I can't see it. I would prefer to leave my hair in place. I'm wondering if that's going to happen as I continue to learn the quirks.
Does loadView ever get called? Put a NSLog (or a breakpoint) in loadView just as a sanity check.
Also, from UIViewController Documentation:
If you override this method (loadView) in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique
instances and should not be shared with any other view controller
object.) Your custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do
so in the viewDidLoad method. In iOS 3.0 and later, you
should also override the viewDidUnload method to release any
references to the view or its contents.
Try putting all the button code in viewDidLoad:
- (void)buttonResponse:(id)sender {
NSLog(#"Button touched up inside!!!!!");
}
- (void)loadView {
// Dont call super (according to the UIViewController docs)
// [super loadView];
// self.view = ... however your setting up self.view
// self.view.frame = CGRectMake....
// self.view.etc...
[self.view setNeedsDisplay];
}
- (void)viewDidLoad {
[super viewDidLoad];
button = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Button" ofType:#"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = [image size];
CGRect buttonFrame = CGRectMake(0,0,imageSize.width + 100, BUTTONBAR_H + 100);
button.frame = buttonFrame;
[button setImage:image forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"" forState:UIControlStateNormal];
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(buttonResponse:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
[self.view bringSubviewToFront:button];
}
- (void)dealloc {
[button release];
[super dealloc];
}