How to load custom view in UIStoryBoard? - ios

I am interested to write my custom view, so I created the following xib file:
This is the definition file:
- (void)_baseInit {
NSLog(#"Unseen View loaded");
[self addSubview:[self activityIndicator]];
[self activityIndicator].alpha = 1.0;
[self activityIndicator].frame = CGRectMake(round(([self imageView].frame.size.width - 25) / 2),
round(([self imageView].frame.size.height - 25) / 2), 25, 25);
[self activityIndicator].hidesWhenStopped = YES;
[self showIndicator];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[self imageView].userInteractionEnabled = YES;
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[[self imageView] addGestureRecognizer:panRecognizer];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self _baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder*)coder
{
if ((self = [super initWithCoder:coder])) {
[self _baseInit];
}
return self;
}
I tried to hook it up in my story board:
And I have my MainViewController call this during viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.unseenView = [[[NSBundle mainBundle] loadNibNamed:#"UnseenView" owner:self options:nil] objectAtIndex:0];
self.unseenView.delegate = self;
Unfortunately, nothing is showing up in my simulator literally nothing, not even the text labels.
However I am seeing the following log messages:
2013-02-20 17:37:58.929 Giordano.iPhone[66857:c07] Unseen View loaded
2013-02-20 17:37:58.934 Giordano.iPhone[66857:c07] Unseen View loaded
What am I doing wrong?

It looks like you are preparing your view correctly, but you are not adding it to the view hierarchy. in the viewDidLoad code you need to add this line:
[self.view addSubview:unseenView];

Related

UIView not Showing in Main View Controller

Hi all I'm implementing in my main ViewController some UIView custom class .. All are shown but only the KPHomeInfluenceUser is not visible .. Definitely it is a stupid question or lack of attention but you can explain why you do not see it ?? What am I doing is a wrong way to implement UIView Custom Class? If my method is wrong you can describe the correct method? I've seen many programmers implement classes this way.... Excuse me for stupid question
- (void)viewDidLoad {
[super viewDidLoad];
[self scrollView];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.calendar clearAllDataToHomeCalendarAndReloadData];
[self.calendar scrollHomeCalendarToCurrentDayAndMonth];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] init];
_scrollView.backgroundColor = [UIColor clearColor];
_scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.scrollView];
[self.scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
[self.scrollView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
[self.scrollView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
[self calendar];
[self influenceUser];
[self homeBottom];
}
return _scrollView;
}
-(KPHomeCalendar *)calendar {
if (!_calendar) {
_calendar = [[KPHomeCalendar alloc] init];
_calendar.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.calendar];
[self.calendar.topAnchor constraintEqualToAnchor:self.baseUserPhoto.topAnchor constant:-5].active = YES;
[self.calendar.leftAnchor constraintEqualToAnchor:self.baseUserPhoto.rightAnchor constant:10].active = YES;
[self.calendar.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-10].active = YES;
[self.calendar.heightAnchor constraintEqualToConstant:85].active = YES;
}
return _calendar;
}
-(KPHomeInfluenceUser *)influenceUser {
KPHomeInfluenceUser *influence = [[KPHomeInfluenceUser alloc] init];
influence.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:influence];
[influence.topAnchor constraintEqualToAnchor:self.calendar.bottomAnchor constant:0].active = YES;
[influence.leftAnchor constraintEqualToAnchor:self.scrollView.leftAnchor constant:10].active = YES;
[influence.rightAnchor constraintEqualToAnchor:self.scrollView.rightAnchor constant:-10].active = YES;
[influence.heightAnchor constraintEqualToConstant:100].active = YES;
return influence;
}

Add action to a programmatically created ImageView

I have created image view through code like this -
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
UIImageView *dot =[[UIImageView alloc] initWithFrame:CGRectMake(50,50,20,20)];
dot.image=[UIImage imageNamed:#"draw.png"];
[self.view addSubview:dot];
}
I want to add User Interaction to this UIImageView and then create a selector or action for this UIImageView when tapped how is this done?
It depends on what kind of action you want achieve. Generally speaking you'd be using UIGestureRecognizer. For instance if you want your image to respond to a tap gesture then you'd have something like the following.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
dotArray = [NSMutableArray alloc]init];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
for(int i = 0; i< 30; i++) {
UIImageView *dot =[[UIImageView alloc] ...
dot.image=[UIImage imageNamed:#"draw.png"];
dot.tag = i; //identify dot image.
[self.view addSubview:dot];
[dotArray addObject:dot];
[dot addGestureRecognizer:tapGesture];
...
}
[tapGesture release];
}
Then the methods to handle tap gesture...
-(void)handleTapGesture:(id)sender {
UITapGestureRecognizer * tapGesture = (UITapGestureRecognizer*)sender;
for(int i = 0; i<[dotArray count]; i++) {
UIImageView * dot = (UIImageView*)[dotArray objectAtIndex:i];
if(dot.tag == [tapGesture view].tag) {
//fade out animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5f];
dot.alpha = 0.0f;
[UIView commitAnimations];
}
For this to work, you need to make an array of dots and declare it as instance variable, otherwise the method can't access the dot.
Try like this:-
UIImageView *dot =[[UIImageView alloc] initWithFrame:CGRectMake(50,50,20,20)];
dot.image=[UIImage imageNamed:#"draw.png"];
[self.view addSubview:dot];
1) To implement the number of touch required is 1 refer this:-
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[dot addGestureRecognizer:doubleTapRecognizer];
- (void)doubleTapped:(UITapGestureRecognizer*)recognizer
{
}
2) To implement the number of touch required is 2 refer this:-
UITapGestureRecognizer *twoFingerTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewTwoFingerTapped:)];
twoFingerTapRecognizer.numberOfTapsRequired = 1;
twoFingerTapRecognizer.numberOfTouchesRequired = 2;
[dot addGestureRecognizer:twoFingerTapRecognizer];
- (void)twoFingerTapped:(UITapGestureRecognizer*)recognizer
{
}
Thank you all of you that helped me I put everyones answers together and got this as my final code.
//
// ViewController.m
// InvaderRush
//
// Created by Ajay Venkat on 13/12/2014.
// Copyright (c) 2014 AJTech. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
{
NSArray *dotArray;
}
#end
#implementation ViewController
- (void)viewDidLoad {
UIImageView *dot =[[UIImageView alloc] initWithFrame:CGRectMake(50,50,100,100)];
dot.image=[UIImage imageNamed:#"invader.jpg"];
[self.view addSubview:dot];
dot.tag = 1; //identify dot image.
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doubleTapped:)];
doubleTapRecognizer.numberOfTouchesRequired = 1;
[dot addGestureRecognizer:doubleTapRecognizer];
dot.userInteractionEnabled = YES;
NSMutableArray *images =[[NSMutableArray alloc] initWithObjects: dot,nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)doubleTapped:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*)sender;
UIImageView *imageView = (UIImageView *)recognizer.view;
if(imageView.tag==1) {
[imageView setImage:[UIImage imageNamed:#"space_invader.jpg"]];
}
}
-(void)handleTapGesture:(id)sender {
}
#end

Objective C Subclass UITextField to copy only

I'm trying to create a class that makes a read only text field that allows the user to copy its contents. Here is my code:
CopyOnly.h
#import <UIKit/UIKit.h>
#interface CopyOnly : UITextField
#end
CopyOnly.m
#import "CopyOnly.h"
#implementation CopyOnly
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self attachTapHandler];
}
return self;
}
- (void) attachTapHandler
{
[self setUserInteractionEnabled:YES];
UIGestureRecognizer *touchy = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[self addGestureRecognizer:touchy];
}
- (BOOL) canPerformAction: (SEL) action withSender: (id) sender
{
return (action == #selector(copy:));
}
- (void) handleTap: (UIGestureRecognizer*) recognizer
{
[self becomeFirstResponder];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:self.frame inView:self.superview];
[menu setMenuVisible:YES animated:YES];
}
- (void)copy:(id)sender
{
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board setString:self.text];
self.highlighted = NO;
[self resignFirstResponder];
}
- (BOOL) canBecomeFirstResponder
{
return YES;
}
#end
This works great, only the keyboard is coming up. I don't want any keyboard to come up.
I tried adding this to initWithFrame:
UIView* noKeyboard = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
self.inputView = noKeyboard;
This does not give me the result I'm expecting. Anyone know how I can do this?
Extending on my comment. This is easily accomplished using a UITextView (not UITextField) with editable property set to NO.
UITextView* tf = [[UITextView alloc] initWithFrame:CGRectMake(50, 50, 200, 50)];
tf.editable = NO;
tf.text = #"Hey this is a test!";
[self.view addSubview:tf];
Adding this to -(BOOL)canBecomeFirtResponder seemed to do the trick. Hacky, but it works.
- (BOOL) canBecomeFirstResponder
{
UIView* noKeyboard = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
self.inputView = noKeyboard;
return YES;
}
If you stuck with text field that doesn't allow editing try totally different approach. Follow instructions in this article http://nshipster.com/uimenucontroller/ to implement UILabel that supports copying.

Getting memory leak in UIKit?

when I tested my App in instruments for memory leak I found nothing(running using simulator).But When I run it in a mobile and then checked, there are many leaks in UIKit objects. This happening in every view.In simulator no such leaks are showing.
Below is the screenshot of the instrument where some leakage happened.
When I moved to secondViewController from HomeView, no leaks found.If again coming back to home,these many leaks are found. So, is it mean that, I have to release/nil all the UI objects which I used in that secondView. For your information, below are the UI objects I used in secondView.
1.Two Background UIImageView
2.One TitleBar UIImageView
3.3 UIButtons(Back,left and right button for iCarousel)
4.One iCarousel view
5.UIPageController(For this I have used a third Party code SMPageControl)
6.One title label.
Note : Mine is Non-ARC code.
Did anyone faced this problem before.How can I overcome this problem,since I have this problem in every View in my App.Because of this, my App getting memory waring frequently and crashing often.
Thank you.
Below is the my implementation file of that View.
EDIT1 :
#implementation CatalogueViewController
#synthesize deptCarousel = _deptCarousel;
#synthesize carouselItems = _carouselItems;
#synthesize categorymAr = _categorymAr;
#synthesize spacePageControl = _spacePageControl;
#synthesize wrap;
- (void)dealloc {
_deptCarousel = nil;
[_categorymAr release];
_categorymAr = nil;
_deptCarousel.delegate = nil;
_deptCarousel.dataSource = nil;
[_deptCarousel release];
[_carouselItems release];
[viewGesture release];
viewGesture = nil;
[_spacePageControl release];
_spacePageControl = nil;
imgViewBG = nil;
imgViewBG2 = nil;
btnPrev = nil;
btnNext = nil;
// [self releaseObjects];
[super dealloc];
}
- ( IBAction) btnBackClicked {
[self.navigationController popViewControllerAnimated:YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = NSLocalizedString(#"catalogue", #"Catalogue");
// Do any additional setup after loading the view from its nib.
_deptCarousel.type = iCarouselTypeLinear;
_deptCarousel.scrollSpeed = 0.3f;
_deptCarousel.bounceDistance = 0.1f;
_deptCarousel.scrollToItemBoundary = YES;
_deptCarousel.stopAtItemBoundary = YES;
[_deptCarousel setScrollEnabled:NO];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeNext:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[viewGesture addGestureRecognizer:swipeLeft];
[swipeLeft release];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipePrev:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[viewGesture addGestureRecognizer:swipeRight];
[swipeRight release];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[viewGesture addGestureRecognizer:singleTap];
[singleTap release];
_carouselItems = [[NSMutableArray alloc] initWithCapacity:1];
_categorymAr = [[NSMutableArray alloc] initWithCapacity:1];
[self addCatalogues];
_spacePageControl.numberOfPages = [_categorymAr count];
[_spacePageControl setPageIndicatorImage:[UIImage imageNamed:IS_IPAD?#"Marker1.fw.png" : #"Markeri.png"]];
[_spacePageControl setCurrentPageIndicatorImage:[UIImage imageNamed:IS_IPAD?#"Marker-Highlight.png" : #"Marker-Highlight_i.png"]];
[_spacePageControl addTarget:self action:#selector(spacePageControl:) forControlEvents:UIControlEventValueChanged];
}
- (void)spacePageControl:(SMPageControl *)sender{
[_deptCarousel scrollToItemAtIndex:sender.currentPage animated:YES];
}
- ( void ) addCatalogues {
[_categorymAr addObjectsFromArray:[[DBModel database] categoryList]];
for (int i = 0; i < [_categorymAr count]; i++) {
[_carouselItems addObject:[NSNumber numberWithInt:i]];
}
[_deptCarousel reloadData];
}
- (void)viewDidUnload{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[self phoneType];
[super viewWillAppear:animated];
if (IS_IPAD) {
UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation];
[self handleOrientation:statusBarOrientation];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- ( void ) phoneType{
if(!IS_IPAD){
if(IS_IPHONE5){
imgViewBG.image = [UIImage imageNamed:#"Background5_5.jpg"];
imgViewBG.center = CGPointMake(162,265);
imgViewBG2.image = [UIImage imageNamed:#"Background11_5.png"];
_spacePageControl.center = CGPointMake(160, 478);
_deptCarousel.center = CGPointMake(160, 355);
viewGesture.center = CGPointMake(160, 355);
btnPrev.center = CGPointMake(25, 355);
btnNext.center = CGPointMake(295, 355);
}
else{
imgViewBG.image = [UIImage imageNamed:#"Background5.jpg"];
imgViewBG2.image = [UIImage imageNamed:#"Background9.png"];
}
}
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
textFieldSearch.placeholder = #"";
UIButton *clearButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[clearButton setImage:[UIImage imageNamed:IS_IPAD?#"Btn_X_Large.fw.png":#"Btn_X.fw.png"] forState:UIControlStateNormal];
[clearButton addTarget:self action:#selector(btnClearTextField) forControlEvents:UIControlEventTouchUpInside];
[textFieldSearch setRightViewMode:UITextFieldViewModeAlways];
[textFieldSearch setRightView:clearButton];
[clearButton release];
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
[textFieldSearch setRightView:nil];
if ([textFieldSearch.text isEqualToString:#""]) {
textFieldSearch.placeholder = NSLocalizedString(#"hud_search_for_a_product_here",#"");
}
}
-(IBAction)btnClearTextField{
textFieldSearch.text = #"";
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (IS_IPAD) {
return YES;
} else {
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation )toInterfaceOrientation duration:(NSTimeInterval)duration{
if (IS_IPAD) {
[self handleOrientation:toInterfaceOrientation];
}
}
- ( void ) handleOrientation:(UIInterfaceOrientation )toInterfaceOrientation {
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
imgViewBG.image = [UIImage imageNamed:#"Background_Catalogue_P.jpg"];
imgViewBG2.image = [UIImage imageNamed:#"Background_Overlay_P.fw.png"];
btnPrev.center = CGPointMake(90, 640);
btnNext.center = CGPointMake(677, 640);
textFieldSearch.frame = CGRectMake(187, 54, 418, 25);
_deptCarousel.frame = CGRectMake(235, 250, 300, 800);
_spacePageControl.center = CGPointMake(385, 920);
viewGesture.center = CGPointMake(385, 658);
}else {
imgViewBG.image = [UIImage imageNamed:#"Background_Catalogue_L.jpg"];
imgViewBG2.image = [UIImage imageNamed:#"Background_Overlay_L.fw.png"];
btnPrev.center = CGPointMake(54, 385);
btnNext.center = CGPointMake(640, 385);
textFieldSearch.frame = CGRectMake(240, 55, 567, 25);
_deptCarousel.frame = CGRectMake(50, 250, 600, 300);
_spacePageControl.center = CGPointMake(346, 660);
viewGesture.center = CGPointMake(347, 405);
}
}
- ( IBAction )btnDepartmentClicked:(id)sender {
int btnTag = [sender tag];
ProductCategoriesViewController *productView = [[ProductCategoriesViewController alloc] initWithNibName:#"ProductCategoriesView" bundle:nil];
if ( btnTag == 0 ) {
[productView setStrTitle:NSLocalizedString(#"women", #"Women")];
}else if ( btnTag == 1 ) {
[productView setStrTitle:NSLocalizedString(#"men", #"Men")];
} else {
[productView setStrTitle:NSLocalizedString(#"sports", #"Sports")];
}
[self.navigationController pushViewController:productView animated:YES];
[productView release];
}
- ( BOOL ) textFieldShouldReturn:( UITextField * )textField {
[textField resignFirstResponder];
[Flurry logEvent:#"Product searched" withParameters:[NSDictionary dictionaryWithObjectsAndKeys:textField.text,#"1", nil]];
[self productSearch:textField.text isBar:NO isQR:NO];
return YES;
}
- ( void ) productSearch:( NSString * )_searchText isBar:( BOOL )_isBar isQR:( BOOL )_isQr {
if ([_searchText isEqualToString:#""]) {
return;
}
NSMutableArray *ProductList = [[NSMutableArray alloc] init];
[ProductList addObjectsFromArray:[[DBModel database] productSearch:_searchText isBar:_isBar isQR:_isQr]];
if ( [ProductList count] == 0 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"product", #"")
message:NSLocalizedString(#"cannot_find_product", #"")
delegate:nil
cancelButtonTitle:NSLocalizedString(#"ok", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
} else {
GeneralProductListViewController *generalProductList = [[GeneralProductListViewController alloc] initWithNibName:IS_IPAD?#"GeneralProductListView~iPad": #"GeneralProductListView" bundle:nil];
[generalProductList setMArProducts:ProductList];
[self.navigationController pushViewController:generalProductList animated:YES];
[generalProductList release];
}
[ProductList release];
}
-(IBAction) spin:(id)sender {
if([sender tag]==0)
{
[_deptCarousel scrollToItemAtIndex:[self.deptCarousel currentItemIndex]+1 animated:YES];
// [_deptCarousel scrollByNumberOfItems:1 duration:2.0];
}
else{
[_deptCarousel scrollToItemAtIndex:[self.deptCarousel currentItemIndex]-1 animated:YES];
}
}
-(void)swipeNext:(UISwipeGestureRecognizer *)recognizer{
[_deptCarousel scrollToItemAtIndex:[self.deptCarousel currentItemIndex]+1 animated:YES];
}
-(void)swipePrev:(UISwipeGestureRecognizer *)recognizer{
[_deptCarousel scrollToItemAtIndex:[self.deptCarousel currentItemIndex]-1 animated:YES];
}
-(void) handleSingleTap:(UITapGestureRecognizer *)recognizer{
if ([_categorymAr count] > 0) {
ProductCategoriesViewController *prodCatView = [[ProductCategoriesViewController alloc] initWithNibName:IS_IPAD ?
#"ProductCategoriesView~iPad" : #"ProductCategoriesView" bundle:nil];
Category *categoryObj = [_categorymAr objectAtIndex:[self.deptCarousel currentItemIndex]];
[prodCatView setStrTitle:categoryObj.categoryName];
[prodCatView setCategoryId:categoryObj.categoryId];
[Flurry logEvent:#"Category List" withParameters:[NSDictionary dictionaryWithObjectsAndKeys:categoryObj.categoryName,[NSString stringWithFormat:#"%d",categoryObj.categoryId], nil]];
[self.navigationController pushViewController:prodCatView animated:YES];
[prodCatView release];
}
}
//-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// pageControl.currentPage = [self.deptCarousel currentItemIndex] ;
//}
#pragma mark
#pragma mark NavigationBarViewDelegate metho
- ( void ) navigationBackClicked {
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark iCarousel methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [_carouselItems count];
}
- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel
{
//limit the number of items views loaded concurrently (for performance reasons)
return NUMBER_OF_VISIBLE_ITEMS;
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index
{
Category *categoryObj = [_categorymAr objectAtIndex:index];
//create a numbered view
UIView *view = nil;
NSString *imagePath = [[APP_CACHES_DIR stringByAppendingPathComponent:#"catalogues"] stringByAppendingString:[NSString stringWithFormat:#"/%d.jpg", categoryObj.categoryId]];
if (![[NSFileManager defaultManager] fileExistsAtPath:imagePath]) {
view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:IS_IPAD?#"Gallery Placeholder.png":#"Gallery Placeholder.png"]] autorelease];
} else {
view = [[[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[APP_CACHES_DIR stringByAppendingPathComponent:#"catalogues"] stringByAppendingString:[NSString stringWithFormat:#"/%d.jpg", categoryObj.categoryId]]]] autorelease];
}
if (IS_IPAD) {
view.frame = CGRectMake(0, 0, 420, 420);
} else {
view.frame = CGRectMake(0, 0, 200, 200);
}
// UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(view.bounds.origin.x, view.bounds.origin.y+view.bounds.size.height, view.bounds.size.width, 44)] autorelease];
// label.text = categoryObj.categoryName;
// label.textColor = [UIColor blackColor];
// label.backgroundColor = [UIColor clearColor];
// label.textAlignment = UITextAlignmentCenter;
// label.font = [UIFont fontWithName:#"Helvetica-Bold" size:IS_IPAD?26:14];
// [view addSubview:label];
return view;
}
- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel
{
//note: placeholder views are only displayed on some carousels if wrapping is disabled
return INCLUDE_PLACEHOLDERS? 2: 0;
}
- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index
{
//create a placeholder view
UIView *view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#""]] autorelease];
UILabel *label = [[[UILabel alloc] initWithFrame:view.bounds] autorelease];
label.text = (index == 0)? #"[": #"]";
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [label.font fontWithSize:50];
_spacePageControl.currentPage = index;
// [view addSubview:label];
return view;
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel
{
//usually this should be slightly wider than the item views
return ITEM_SPACING;
}
- (CATransform3D)carousel:(iCarousel *)_carousel transformForItemView:(UIView *)view withOffset:(CGFloat)offset
{
//implement 'flip3D' style carousel
//set opacity based on distance from camera
view.alpha = 1.0 - fminf(fmaxf(offset, 0.0), 1.0);
//do 3d transform
CATransform3D transform = CATransform3DIdentity;
transform.m34 = _deptCarousel.perspective;
transform = CATransform3DRotate(transform, M_PI / 8.0, 0, 1.0, 0);
return CATransform3DTranslate(transform, 0.0, 0.0, offset * _deptCarousel.itemWidth);
}
- (BOOL)carouselShouldWrap:(iCarousel *)carousel
{
//wrap all carousels
// return NO;
return wrap;
}
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index {
if (index == [self.deptCarousel currentItemIndex]) {
ProductCategoriesViewController *prodCatView = [[ProductCategoriesViewController alloc] initWithNibName:IS_IPAD ?
#"ProductCategoriesView~iPad" : #"ProductCategoriesView" bundle:nil];
Category *categoryObj = [_categorymAr objectAtIndex:index];
[prodCatView setStrTitle:categoryObj.categoryName];
[prodCatView setCategoryId:categoryObj.categoryId];
[Flurry logEvent:#"Category List" withParameters:[NSDictionary dictionaryWithObjectsAndKeys:categoryObj.categoryName,[NSString stringWithFormat:#"%d",categoryObj.categoryId], nil]];
[self.navigationController pushViewController:prodCatView animated:YES];
[prodCatView release];
}
}
-(void) carouselDidScroll:(iCarousel *)carousel{
// [_deptCarousel scrollToItemAtIndex:[self.deptCarousel currentItemIndex]+3 animated:YES];
// [_deptCarousel scrollByNumberOfItems:1 duration:1];
}
- (void)carouselCurrentItemIndexUpdated:(iCarousel *)carousel{
_spacePageControl.currentPage = [self.deptCarousel currentItemIndex];
}
- ( IBAction ) myCart {
if ( [[DBModel database] isShoppingListEmpty] ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"at_shopping_cart", #"")
message:NSLocalizedString(#"amsg_shopping_cart_empty", #"")
delegate:nil cancelButtonTitle:NSLocalizedString(#"ok", #"") otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
MyCartViewController *myCartView = [[MyCartViewController alloc] initWithNibName:IS_IPAD ? #"MyCartView~iPad" : #"MyCartView" bundle:nil];
[self.navigationController pushViewController:myCartView animated:YES];
[myCartView release];
}
First, as noted before, use ARC. There is no single thing you could do that will more improve memory management.
Whether you use ARC or not, you should always use accessors to access your ivars (except in init and dealloc). As noted by #LombaX, you're setting your ivars incorrectly in viewDidLoad. Using accessors would help this.
You should run the static analyzer, which will help you find other memory mistakes.
I would suspect that you have an IBOutlet that is configured as retain and that you are not releasing in dealloc. That is the most likely cause of the leaks I'm seeing in your screenshots. ARC will generally make such problems go away automatically.
It is very possible that you have a retain loop. This generally would not show up as a leak. You should use heapshot to investigate that. Your leaks are pretty small; they may not be the actual cause of memory warnings. What you want to investigate (with the Allocations instrument) is what is actually significantly growing your memory use.
But first ARC. Then accessors. Then remove all build warnings. Then remove all Static Analyzer warnings. Then use the Allocations instrument.
Side note: the fact that it says the responsible party is "UIKit" does not mean that this is a bug in UIKit. It just means that UIKit allocated the memory that was later leaked. The cause of the leak could be elsewhere. (That said, UIKit does have several small leaks in it. In general they should not give you trouble, but you may never be able to get rid of 100% of small leaks in an iOS app.)
First:
you have a possible and visible leak, but I'm not sure if it is the same leak you have found in instruments:
These two lines are in your viewDidLoad method
_carouselItems = [[NSMutableArray alloc] initWithCapacity:1];
_categorymAr = [[NSMutableArray alloc] initWithCapacity:1];
But: viewDidLoad: is called every time the view is loaded by it's controller. If the controller purges the view (for example after a memory warning), at the second viewDidLoad your _carouselItems and _categorymAr instance variables will lost the reference to the previously created NSMutableArray, causing a leak
So, change that lines and use the syntesized setters:
self.carouselItems = [[[NSMutableArray alloc] initWithCapacity:1] autorelease];
self.categorymAr = [[[NSMutableArray alloc] initWithCapacity:1] autorelease];
the syntesized setter is configured to release the previous object before assignin a new one.
However: it's possible that you have another leak.
If you can reproduce the leak simply (if I understand, the leak appears simply moving from a VC to another), you can use the "heapshot" function of instruments.
Assuming that your leak appears moving from the first VC to the second and coming back:
open instruments with the allocations tool
go from the first VC to the second and come back.
press "mark heap" on the left. A line will appear.
go again from the first VC to the second and come back.
press "heapshot" again
do this several times (9-10)
the heapshot tool takes a "snapshot" of the living objects at the time you pushed the button and shows you only the difference.
If there are 2-3 new objects, you will see it in the list.
This is a good starting point to investigate a leak.
Look at the attached image:
Consider that you must mark the heap several time and discriminate "false positive" by looking at the object created, in my example you can se a possible leak (heapshot5, 1,66KB), but after looking at the content it's not --> it was a background task that started in that moment.
Moreover, delays of the autorelease pool and the cache of some UIKit objects can show something in the heapshot, this is why I say to try it several times.
One easy way to detect where your leaks come from is to use the Extended Detail view of the Instruments.
To do that click on "View"->"Extended detail" and a right menu with the stack trace of the "leak" will appear. There you will easily find the leaking code for each leak and if they come from your app.

Why does my CvVideoCamera cover the whole view?

I'm using a CvVideo Camera thus:
- (void)viewDidLoad
{
[super viewDidLoad];
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetiFrame960x540;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.videoCamera start];
}
My storyboard looks like this:
When the view loads, the bar is visible briefly with the rest of the view white. Then when the camera starts it fills the whole screen. Why is it doing this?
Have you tried with a different parent view?
UIView *camView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 300, 400)];
[self.view addSubview:camView];
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:camView];

Resources