apple beginner here. Im currently studying and trying the iCarousel by nickLockwood. Im planning on putting images in the iCarousel. So here's my .m and .h code:
// .m
#implementation ViewController
#synthesize images;
...
- (void)awakeFromNib
{
if (self) {
//set up carousel data
//wrap YES = infinite loop
wrap = YES;
self.images = [NSMutableArray arrayWithObjects:
#"apple.jpg",#"lemon.jpg",#"orange.jpg",#"melon.jpg",#"mango.jpg",nil];
}
}
- (UIView *)carousel:(iCarousel *)_carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
if (view == nil)
{
view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[images objectAtIndex:index]]];
}
return view;
}
// .h
#interface ViewController : UIViewController <iCarouselDataSource, iCarouselDelegate>{
NSMutableArray *images;
...
}
#property (nonatomic,retain) NSMutableArray *images;
…
#end
I was planning on adding 30 images so I want the code to be maintainable.
My problem is I want to be able to get the image by NSBundle or from the applications directory, I've tried different codes but the image doesn't appear in the carousel. Thanks for your help.
Hey here is some code of mine that i used in my iCarousel app. You are missing some methods. So here they are.
#pragma mark iCarousel methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [items count];
}
- (NSUInteger)numberOfVisibleItemsInCarousel:(iCarousel *)carousel
{
//limit the number of items views loaded concurrently (for performance reasons)
//this also affects the appearance of circular-type carousels
return 7;
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[items objectAtIndex:index]]];
return view;
}
- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel
{
//note: placeholder views are only displayed on some carousels if wrapping is disabled
return 0;
}
- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[items objectAtIndex:index]]];
return view;
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel
{
//usually this should be slightly wider than the item views
return ITEM_SPACING;
}
- (CGFloat)carousel:(iCarousel *)carousel itemAlphaForOffset:(CGFloat)offset
{
//set opacity based on distance from camera
return 1.0f - fminf(fmaxf(offset, 0.0f), 1.0f);
}
- (CATransform3D)carousel:(iCarousel *)_carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
{
//implement 'flip3D' style carousel
transform = CATransform3DRotate(transform, M_PI / 8.0f, 0.0f, 1.0f, 0.0f);
return CATransform3DTranslate(transform, 0.0f, 0.0f, offset * carousel.itemWidth);
}
- (BOOL)carouselShouldWrap:(iCarousel *)carousel
{
return wrap;
}
- (void)carouselDidEndScrollingAnimation:(iCarousel *)aCarousel
{
[labelDescription setText:[NSString stringWithFormat:#"%#", [descriptions objectAtIndex:aCarousel.currentItemIndex]]];
}
Hope this helps.
Related
I have an array that contains 20 images add that images to imageview using scrollview. all image scroll.
I want to add the Carousel circle effect for all my 20 images how may i do thsi i have tried this but not work.
Adding iCarousel.h,iCarousel.m into my bundle defining delegate also.
<iCarouselDataSource,iCarouselDelegate,UIScrollViewDelegate>
-(void)viewDidLoad
{
iCarousel *icrusal = [[iCarousel alloc]initWithFrame:CGRectMake(0,0, 320, 480)];
icrusal.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
icrusal.delegate = self;
icrusal.dataSource = self;
icrusal.type=iCarouselTypeRotary;
icrusal.type=iCarouselTypeCoverFlow;
[self.view addSubview:icrusal];
}
-(NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return 20;
}
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index
{
//ImgView=[[UIImageView alloc]init];
ImgView=[[UIImageView alloc]init];
return ImgView;
}
- (BOOL)carousel:(iCarousel *)carousel shouldSelectItemAtIndex:(NSInteger)index{
return YES;
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel
{
//usually this should be slightly wider than the item views
return 180;
}
how may i do this thanks in advance.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50.0f, 50.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"apple-logo-1.png"];
view.contentMode = UIViewContentModeCenter;
}
else
{
//get a reference to the label in the recycled view
((UIImageView *)view).image = [UIImage imageNamed:#"apple-logo-1.png"];
}
return view;
}
And you can also add below method to give space between images in iCarousel
- (CGFloat)carousel:(iCarousel *)_carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
//customize carousel display
switch (option)
{
case iCarouselOptionWrap:
{
//normally you would hard-code this to YES or NO
return NO;
}
case iCarouselOptionSpacing:
{
//add a bit of spacing between the item views
return value * 1.95f;
}
case iCarouselOptionFadeMax:
{
if (_carousel.type == iCarouselTypeCustom)
{
//set opacity based on distance from camera
return 0.0f;
}
return value;
}
default:
{
return value;
}
}
}
This may help ypu.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
if (view == nil)
{
NSString *strStarImg=[[yourarrayofImage objectAtIndex:index] valueForKey:#"keyofImage"];
ImgView = [UIImageView alloc] initWithImage:[UIImage imageNamed:strStarImg];
//you can define frame of your imageview here...ImgView.frame=CGRectMake(0, 450, 768, 462);
[view addSubview:img];
return view;
}
let me know it is working or not..!!
Happy Coding....!!!
I am trying to update the UILabel of IBOutlet, however for some reason the content is not getting updated. Initially, the content is getting loaded from the model, which performs jsonResponse in async. However, I have set a delegate once the content is there to update the layout for which I am calling setNeedsDisplay.
Any help here would be appreciated.
Thanks.
The code below:
#interface pd ()
#property (nonatomic,retain) NSDictionary *pD;
#property (nonatomic, retain) pd_model *pdModel;
#end
#implementation pd
#synthesize pD = _pD, pdModel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil :(NSDictionary*)pD {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.productDetails = [[NSDictionary alloc] initWithDictionary:pD];
self.pdModel = [[ProductDetails_Model alloc] init:pD];
self.pdModel.delegate = self;
NSLog(#"%#",[self.pD description]);
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[scrollView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:scrollView];
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.scrollEnabled = YES;
// Do any additional setup after loading the view from its nib.
productRecCarousel = [[iCarousel alloc] initWithFrame:CGRectMake(0.0f, scrollView.contentSize.height, 320.0f, 100.0)];
productRecCarousel.delegate = self;
[scrollView addSubview:productRecCarousel];
[self addProductDescription];
NSLog(#"%#",[self.pdModel responseCode]);
[soldBy setText:[self.pdModel responseCode]];
//[soldBy setText:#"1"];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark
#pragma mark CarouselDelegate methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
return 1;
}
- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel {
return 1;
}
- (UIView*)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
return [[UIView alloc] init];
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel {
//usually this should be slightly wider than the item views
return 150;
}
- (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 = _carousel.perspective;
transform = CATransform3DRotate(transform, M_PI / 8.0, 0, 1.0, 0);
return CATransform3DTranslate(transform, 0.0, 0.0, offset * _carousel.itemWidth);
}
- (void)addProductDescription {
NSLog(#"%f",addProductDetails.frame.size.height);
addProductDetails.frame = CGRectMake(0.0f, productRecCarousel.frame.size.height, addProductDetails.frame.size.width, addProductDetails.frame.size.height);
[scrollView addSubview:addProductDetails];
}
- (void)updateTheLayout {
//[self.view setNeedsDisplay];
//This is where I get the delegate called once the model is being updated. I tried scrollView and self.view setNeedsDisplay and setNeedsLayout but the IBoutlet never gets updated which is in "ViewDidLoad as assigned as" : [soldBy setText:[self.pdModel responseCode]];
}
Thanks.
so you just have to call [soldBy setText:[self.pdModel responseCode]]; from updateTheLayout and not from viewDidLoad because it is not ready yet. And please make sure to update the UI elements from the main thread.
You have to call [soldBy setText:[self.pdModel responseCode]]; in your callback, not in the viewDidLoad method.
ive created coverflow effect using icarousel,but i've added two buttons not by programmatically in xib and i defined outlet and action and connected for that buttons..but those buttons are displayed as image and not working...Here is my code in .m file
#interface GoldViewController ()<UIActionSheetDelegate>
#property (nonatomic, assign) BOOL useButtons;
#end
#implementation GoldViewController
#synthesize carousel1;
-(IBAction)showhome:(id)sender{
ViewController *sec=[[ViewController alloc]initWithNibName:Nil bundle:Nil];
sec.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[self presentModalViewController:sec animated:YES];
}
-(IBAction)showback:(id)sender{
CollectionsViewController *sec=[[CollectionsViewController alloc]initWithNibName:Nil bundle:Nil];
sec.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[self presentModalViewController:sec animated:YES];
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
carousel1.type = iCarouselTypeCylinder;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return NUMBER_OF_ITEMS;
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIImage *buttonImage=[NSArray arrayWithObjects:[UIImage imageNamed:#"ban.jpg"],
[UIImage imageNamed:#"pen.jpg"],
[UIImage imageNamed:#"ear1.jpg"],
[UIImage imageNamed:#"neck.jpg"],
[UIImage imageNamed:#"brac.jpg"],
[UIImage imageNamed:#"rings.jpg"],nil];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 250.0f, 320.0f);
[button setImage:(UIImage*)[buttonImage objectAtIndex:index] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
return button;
}
- (CGFloat)carouselItemWidth:(iCarousel *)carousel
{
return ITEM_SPACING;
}
- (BOOL)carousel:(iCarousel *)_carousel shouldSelectItemAtIndex:(NSInteger)index
{
if (index == carousel1.currentItemIndex)
{
NSLog(#"Should select current item");
}
else
{
NSLog(#"Should select item number %i", index);
}
return YES;
}
- (void)carousel:(iCarousel *)_carousel didSelectItemAtIndex:(NSInteger)index
{
if (index == carousel1.currentItemIndex)
{
//note, this will only ever happen if useButtons == NO
//otherwise the button intercepts the tap event
NSLog(#"Did select current item");
}
else
{
NSLog(#"Did select item number %i", index);
}
}
#end
Make sure that the nib files owner is definitely GoldViewController. Check that you've definitely added the buttons to the nib as buttons and not images. Make sure touchupinside action on each relevant button is connected to the showhome and showback actions in the nib files owner.
If all of this is ok, its possible that when the view controllers view is being displayed, the iCarousel's view is overlaying your button views. (I seem to recall some issues with iCarousel not laying out the view at runtime to be in the same place as defined in the nib but don't remember details). To find out - log the frame of the buttons and of the iCarousel view in your viewWillAppear method.
You can scroll an UIPickerView both by swiping and by tapping items under or above the selection belt.
You can populate an UIPickerView by either specifying NSString as titles or reusable UIViews for each row.
What I've noticed is that when I switched from providing strings to providing view, tap to scroll no longer worked. Is this expected behavior. Should my views forward some touch events to the UIPickerView?
Thanks
EDIT:
Here's a code sample from my implementation:
// Creating the picker
screenPicker_ = [UIPickerView new];
screenPicker_.showsSelectionIndicator = YES;
screenPicker_.delegate = delegate_;
screenPicker_.dataSource = delegate_;
[self addSubview:screenPicker_];
[screenPicker_ release];
// Row view creation delegate
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
PickerRowView *pickerRowView = (PickerRowView*)view;
if(view == nil)
{
pickerRowView = [[PickerRowView alloc] initWithFrame:CGRectMake(0, 0, pickerView.frame.size.width, PICKER_ROW_HEIGHT)];
}
[pickerRowView SetTitle:#"some title"];
return pickerRowView;
}
// initailizer of the PickerRowView class (an UIView subclass)
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
CGFloat titleHeight = frame.size.height * CONTENT_TO_FRAME_RATIO;
title_ = [[UILabel alloc] initWithFrame:CGRectMake(TITLE_X, (frame.size.height - titleHeight) / 2, frame.size.width, titleHeight)];
[title_ setFont:[UIFont fontWithName:#"StainlessExt-Light" size:titleHeight]];
title_.backgroundColor = [UIColor clearColor];
[self addSubview:title_];
[title_ release];
self.userInteractionEnabled = NO;
}
return self;
}
Setting userInteractionEnabled property to NO for your row views must solve your problem.
In your PickerRowView class, define the following method:
- (void)didMoveToSuperview {
if ([[self superview] respondsToSelector:#selector(setShowSelection:)])
{
[[self superview] performSelector:#selector(setShowSelection:) withObject:NO];
} }
and that should get rid of the highlight
I have successfully integrated the three20 framework in my project,
and I have extended the TTPhotoViewController to add some further
functionality.
Now I need to add some subviews to the TTPhotoView loaded by the
TTPhotoViewController. In particular I would like to add that subviews
after every TTPhotoView as been loaded. These subviews represents
sensible area over the image so they should scale proportionally with
the image.
The user can tap a subview to get extra info about the image.
I don't know how to implement this behavior. Should I extend the
TTPhotoView and make sure that the TTPhotoViewController use this
extended version instead of its TTPhotoView?
Could someone point me to the right direction?
Thank you
Solved subclassing the TTPhotoView (TapDetectingPhotoView) and then adding all my subviews to that subclass.
The main problem was represented by the photo switching, because the TTPhotoViewController (in particular its inner TTScrollView) reuse the TTPhotoView during switching operation.
So for example if you add your subview to your TTPhotoView subclass and try to switch to the next photo, your subview will probably be here, because the TTPhotoView is reused.
To solve this problem I decided to add and remove all my subviews every time a photo switch occur (see TTPhotoViewController::didMoveToPhoto).
In this way I'm sure that every photoview has its subviews.
Here my implementation (only remarkable methods)
Hope these help!
PhotoViewController.h:
#import "TapDetectingPhotoView.h"
#interface PhotoGalleryController : TTPhotoViewController <TTScrollViewDelegate, TapDetectingPhotoViewDelegate> {
NSArray *images;
}
#property (nonatomic, retain) NSArray *images;
#end
PhotoViewController.m:
#import "PhotoGalleryController.h"
#implementation PhotoGalleryController
#synthesize images;
- (void)viewDidLoad { // fill self.images = ... }
- (TTPhotoView*)createPhotoView {
TapDetectingPhotoView *photoView = [[TapDetectingPhotoView alloc] init];
photoView.tappableAreaDelegate = self;
return [photoView autorelease];
}
#pragma mark -
#pragma mark TTPhotoViewController
- (void)didMoveToPhoto:(id<TTPhoto>)photo fromPhoto:(id<TTPhoto>)fromPhoto {
[super didMoveToPhoto:photo fromPhoto:fromPhoto];
TapDetectingPhotoView *previousPhotoView = (TapDetectingPhotoView *)[_scrollView pageAtIndex:fromPhoto.index];
TapDetectingPhotoView *currentPhotoView = (TapDetectingPhotoView *)[_scrollView pageAtIndex:photo.index];
// destroy the sensible areas from the previous photoview, because the photo could be reused by the TTPhotoViewController!
if (previousPhotoView)
previousPhotoView.sensibleAreas = nil;
// if sensible areas has not been already created, create new
if (currentPhotoView && currentPhotoView.sensibleAreas == nil) {
currentPhotoView.sensibleAreas = [[self.images objectAtIndex:photo.index] valueForKey:#"aMap"];
[self showSensibleAreas:YES animated:YES];
}
}
#pragma mark -
#pragma mark TappablePhotoViewDelegate
// show a detail view when a sensible area is tapped
- (void)tapDidOccurOnSensibleAreaWithId:(NSUInteger)ids {
NSLog(#"SENSIBLE AREA TAPPED ids:%d", ids);
// ..push new view controller...
}
TapDetectingPhotoView.h:
#import "SensibleAreaView.h"
#protocol TapDetectingPhotoViewDelegate;
#interface TapDetectingPhotoView : TTPhotoView <SensibleAreaViewDelegate> {
NSArray *sensibleAreas;
id <TapDetectingPhotoViewDelegate> tappableAreaDelegate;
}
#property (nonatomic, retain) NSArray *sensibleAreas;
#property (nonatomic, assign) id <TapDetectingPhotoViewDelegate> tappableAreaDelegate;
#end
#protocol TapDetectingPhotoViewDelegate <NSObject>
#required
- (void)tapDidOccurOnSensibleAreaWithId:(NSUInteger)ids;
#end
TapDetectingPhotoView.m:
#import "TapDetectingPhotoView.h"
#interface TapDetectingPhotoView (Private)
- (void)createSensibleAreas;
#end
#implementation TapDetectingPhotoView
#synthesize sensibleAreas, tappableAreaDelegate;
- (id)init {
return [self initWithSensibleAreas:nil];
}
- (id)initWithFrame:(CGRect)frame {
return [self initWithSensibleAreas:nil];
}
// designated initializer
- (id)initWithSensibleAreas:(NSArray *)areasList {
if (self = [super initWithFrame:CGRectZero]) {
self.sensibleAreas = areasList;
[self createSensibleAreas];
}
return self;
}
- (void)setSensibleAreas:(NSArray *)newSensibleAreas {
if (newSensibleAreas != self.sensibleAreas) {
// destroy previous sensible area and ensure that only sensible area's subviews are removed
for (UIView *subview in self.subviews)
if ([subview isMemberOfClass:[SensibleAreaView class]])
[subview removeFromSuperview];
[newSensibleAreas retain];
[sensibleAreas release];
sensibleAreas = newSensibleAreas;
[self createSensibleAreas];
}
}
- (void)createSensibleAreas {
SensibleAreaView *area;
NSNumber *areaID;
for (NSDictionary *sensibleArea in self.sensibleAreas) {
CGFloat x1 = [[sensibleArea objectForKey:#"nX1"] floatValue];
CGFloat y1 = [[sensibleArea objectForKey:#"nY1"] floatValue];
area = [[SensibleAreaView alloc] initWithFrame:
CGRectMake(
x1, y1,
[[sensibleArea objectForKey:#"nX2"] floatValue]-x1, [[sensibleArea objectForKey:#"nY2"] floatValue]-y1
)
];
areaID = [sensibleArea objectForKey:#"sId"];
area.ids = [areaID unsignedIntegerValue]; // sensible area internal ID
area.tag = [areaID integerValue];
area.delegate = self;
[self addSubview:area];
[area release];
}
}
// to make sure that if the zoom factor of the TTScrollView is > than 1.0 the subviews continue to respond to the tap events
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *result = nil;
for (UIView *child in self.subviews) {
CGPoint convertedPoint = [self convertPoint:point toView:child];
if ([child pointInside:convertedPoint withEvent:event]) {
result = child;
}
}
return result;
}
#pragma mark -
#pragma mark TapDetectingPhotoViewDelegate methods
- (void)tapDidOccur:(SensibleAreaView *)aView {
NSLog(#"tapDidOccur ids:%d tag:%d", aView.ids, aView.tag);
[tappableAreaDelegate tapDidOccurOnSensibleAreaWithId:aView.ids];
}
SensibleAreaView.h:
#protocol SensibleAreaViewDelegate;
#interface SensibleAreaView : UIView {
id <SensibleAreaViewDelegate> delegate;
NSUInteger ids;
UIButton *disclosureButton;
}
#property (nonatomic, assign) id <SensibleAreaViewDelegate> delegate;
#property (nonatomic, assign) NSUInteger ids;
#property (nonatomic, retain) UIButton *disclosureButton;
#end
#protocol SensibleAreaViewDelegate <NSObject>
#required
- (void)tapDidOccur:(SensibleAreaView *)aView;
#end
SensibleAreaView.m:
#import "SensibleAreaView.h"
#implementation SensibleAreaView
#synthesize delegate, ids, disclosureButton;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.userInteractionEnabled = YES;
UIColor *color = [[UIColor alloc] initWithWhite:0.4 alpha:1.0];
self.backgroundColor = color;
[color release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[button addTarget:self action:#selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];
CGRect buttonFrame = button.frame;
// set the button position over the right edge of the sensible area
buttonFrame.origin.x = frame.size.width - buttonFrame.size.width + 5.0f;
buttonFrame.origin.y = frame.size.height/2 - 10.0f;
button.frame = buttonFrame;
button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
self.disclosureButton = button;
[self addSubview:button];
// notification used to make sure that the button is properly scaled together with the photoview. I do not want the button looks bigger if the photoview is zoomed, I want to preserve its default dimensions
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(zoomFactorChanged:) name:#"zoomFactorChanged" object:nil];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
if ([[touches anyObject] tapCount] == 1)
[delegate tapDidOccur:self];
}
- (void)buttonTouched {
[delegate tapDidOccur:self];
}
- (void)zoomFactorChanged:(NSNotification *)message {
NSDictionary *userInfo = [message userInfo];
CGFloat factor = [[userInfo valueForKey:#"zoomFactor"] floatValue];
BOOL withAnimation = [[userInfo valueForKey:#"useAnimation"] boolValue];
if (withAnimation) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.18];
}
disclosureButton.transform = CGAffineTransformMake(1/factor, 0.0, 0.0, 1/factor, 0.0, 0.0);
if (withAnimation)
[UIView commitAnimations];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"zoomFactorChanged" object:nil];
[disclosureButton release];
[super dealloc];
}
Some ideas:
Subclass TTPhotoView, then override createPhotoView in your TTPhotoViewController:
- (TTPhotoView*)createPhotoView {
return [[[MyPhotoView alloc] init] autorelease];
}
Try overriding a private method (yes, bad practice, but hey) setImage: in TTPhotoView subclass:
- (void)setImage:(UIImage*)image {
[super setImage:image]
// Add a subview with the frame of self.view, maybe?..
//
// Check for self.isLoaded (property of TTImageView
// which is subclassed by TTPhotoView) to check if
// the image is loaded
}
In general, look at the headers and implementations (for the private methods) of TTPhotoViewController and TTPhotoView. Set some breakpoints to figure out what does what :)
Interesting question. Facebook has a similar functionality with their tags. Their tags do not scale proportionally with the image. In fact, they do not even show the tags if you have zoomed. I don't know if this will help you, but I would look at how (if) three20 handles tags and then maybe try to extend that.