1

I want to write a custom UIView that does the following:

  • It takes an image and adds it to a view.
  • It has a method to flip that image.

I want to pass this Custom UIView to the iCarousel class: https://github.com/nicklockwood/iCarousel

How can I create a custom UIView using Objective C and Cocoa?

I started by doing the following:

CItem.h

#import <UIKit/UIKit.h>

@interface CItem : UIView
{
    UIImageView *box;
}

@property (nonatomic, retain) UIImageView * box;


@end

CItem.m

#import "CItem.h"

@implementation CItem

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


- (void)drawRect:(CGRect)rect {
    // Drawing code
    box = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, 240, 240)];

    [box setImage:[UIImage imageNamed:@ "cleaning.png"]];
    [self addSubview:box];
}


@end

2 Answers 2

6

You should not add your addSubview: in drawRect:. See this method's disscussion:

Discussion

The default implementation of this method does nothing. Subclasses that use native drawing technologies (such as Core Graphics and UIKit) to draw their view’s content should override this method and implement their drawing code there. You do not need to override this method if your view sets its content in other ways. For example, you do not need to override this method if your view just displays a background color or if your view sets its content directly using the underlying layer object. Similarly, you should not override this method if your view uses OpenGL ES to do its drawing.

If you don't use a xib file for your CItem you can add your code to initWithFrame:.

//CItem.h
#import <UIKit/UIKit.h>

@interface CItem : UIView

- (void)flip;

@end

// CItem.m
#import "CItem.h"

@interface CItem()

@property (assign, nonatomic) BOOL displayingPrimary;

@property (strong, nonatomic) UIImageView *primaryView;
@property (strong, nonatomic) UIImageView *secondaryView;

@end

@implementation CItem

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _primaryView = [[UIImageView alloc] initWithFrame:frame];
        [_primaryView setImage:[UIImage imageNamed:@ "cleaning.jpg"]];
        [self addSubview:_primaryView];

        _secondaryView = [[UIImageView alloc] initWithFrame:frame];
        [_secondaryView setImage:[UIImage imageNamed:@ "adding.jpg"]];
        [self addSubview:_secondaryView];

    }
    return self;
}

- (void)flip
{
    [UIView transitionFromView:(self.displayingPrimary ? self.primaryView : self.secondaryView)
                        toView:(self.displayingPrimary ? self.secondaryView : self.primaryView)
                      duration:1.0
                       options:(self.displayingPrimary ? UIViewAnimationOptionTransitionFlipFromRight :
                                UIViewAnimationOptionTransitionFlipFromLeft) | UIViewAnimationOptionShowHideTransitionViews
                    completion:^(BOOL finished) {
                        if (finished) {
                            self.displayingPrimary = !self.displayingPrimary;
                        }
                    }];
}

@end

Then you can use CItem like this:

CItem *subView = [[CItem alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];
[self.view addSubview:subView];
Sign up to request clarification or add additional context in comments.

Comments

3

You should only implement drawRect if you intend to do custom drawing. If you want to use subviews you can just move your code into the initWithFrame:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
       box = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 240.0f, 240.0f)];
       [box setImage:[UIImage imageNamed:@"cleaning"]];
       [self addSubview:box];
    }
    return self;
}

You can safely remove the drawRect method. Not sure what you mean by "flipping" the image, but you should be able to manipulate the imageView object using the "box" property of your custom class.

1 Comment

I tried: - (UIView*)carousel:(iCarousel )carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view { // create a numbered view / view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[animals objectAtIndex:index] ] ]; return view; */ CGRect frame = CGRectMake(round((self.view.bounds.size.width - 300) / 2.0), 0, 300, 300); view = [[CItem alloc] initWithFrame: frame]; return view; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.