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.
Related
I have created a horizontal UIPickerView with UIImageViews (instead of textlabels etc). Basically works fine except the images only display on the iPhone simulator, but not on the actual iPhone.
I am building for iOS v 4.3.
I am complete stumped, have been struggling with this for quite some time!
Thanks :)
Below is an extract from the code:
//
// PickerPicViewController.m
// PickerPic
//
// Created by user on 2012/01/11.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "PickerPicViewController.h"
#implementation PickerPicViewController
#synthesize piccie;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 2;
}
- (UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UIImage *one = [UIImage imageNamed:#"rss.png"];
UIImageView *oneView = [[[UIImageView alloc] initWithImage:one] initWithFrame:CGRectMake(0, 0, 50, 50)];
return oneView;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
piccie = [[UIPickerView alloc] initWithFrame:CGRectZero];
piccie.delegate = self;
piccie.dataSource = self;
piccie.showsSelectionIndicator = YES;
piccie.backgroundColor = [UIColor clearColor];
CGRect pickerFrame = piccie.frame;
pickerFrame.size.width = 70;
pickerFrame.size.height = 216;
pickerFrame.origin.x = 125;
pickerFrame.origin.y = 20;
piccie.frame = pickerFrame;
CGAffineTransform rotate = CGAffineTransformMakeRotation(-M_PI/2);
rotate = CGAffineTransformScale(rotate, 1, 1.30);
CGAffineTransform t0 = CGAffineTransformMakeTranslation(1, -40.5);
piccie.transform = CGAffineTransformConcat(rotate, t0);
[self.view addSubview:piccie];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
Why are you initializing uiimageview two times while creating? I think it is the problem. Instead try
UIImageView *oneView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
[oneView setImage: one];
HI i'm tring to create photogallery with two scrollviews
one for horizontal scrolling between images and second for zooming images.
scrolling between images works fine but i'm not able to zoom image into second scrollView.
mainScrollView named VcLicences
VcLicences.h
#import <UIKit/UIKit.h>
#interface VcLicences : UIViewController <UIScrollViewDelegate>{
IBOutlet UIScrollView* scrollView;
IBOutlet UIPageControl* pageControl;
BOOL pageControlIsChangingPage;
}
#property (nonatomic, retain) UIView *scrollView;
#property (nonatomic, retain) UIPageControl* pageControl;
/* for pageControl */
- (IBAction)changePage:(id)sender;
/* internal */
- (void)setupPage;
#end
VcLicences.m
#import "VcLicences.h"
#import "VcImageZoomView.h"
#implementation VcLicences
#synthesize scrollView;
#synthesize pageControl;
- (void)setupPage
{
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor whiteColor]];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleBlack;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
scrollView.multipleTouchEnabled = NO;
NSUInteger nim = 0;
CGFloat cx = 0;
NSArray *licence = [NSArray arrayWithObjects:#"zl1.jpg", #"zl2.jpg", #"zl3.jpg", #"dph.jpg", #"or.jpg", nil];
for (nim=0; nim < [licence count]; nim++)
{
VcImageZoomView *imageZoom = [[VcImageZoomView alloc] initWithNibName:#"VcImageZoomView" bundle:nil];
[imageZoom.view setFrame:CGRectMake(cx, 0, 320, 332)];
[imageZoom setMyImage:[licence objectAtIndex:nim]];
[scrollView addSubview:imageZoom.view];
[imageZoom release];
cx += scrollView.frame.size.width;
}
self.pageControl.numberOfPages = nim;
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
#pragma mark UIScrollViewDelegate stuff
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView
{
if (pageControlIsChangingPage)
{
return;
}
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView
{
pageControlIsChangingPage = NO;
}
- (IBAction)changePage:(id)sender
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pageControl.currentPage;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlIsChangingPage = YES;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
self.navigationItem.title = #"CZECHMAT's licenses";
[self setupPage];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
//[scrollView release];
//[pageControl release];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (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.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
//return (interfaceOrientation == UIInterfaceOrientationPortrait);
return YES;
}
#end
second ScrollView for zooming images named VcImageZoomView
VcImageZoomView.h
#import <UIKit/UIKit.h>
#interface VcImageZoomView : UIViewController <UIScrollViewDelegate>{
IBOutlet UIScrollView *scroll;
UIImageView *image;
}
#property (nonatomic, retain) UIScrollView *scroll;
-(void)setMyImage:(NSString *) imageName;
#end
VcImageZoomView.m
#import "VcImageZoomView.h"
#implementation VcImageZoomView
#synthesize scroll;
-(void)setMyImage:(NSString *) imageName;
{
NSLog(#"%#", imageName);
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
float scaleWidth = scroll.frame.size.width / image.frame.size.width;
float scaleHeight = scroll.frame.size.height / image.frame.size.height;
float scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
NSLog(#"%f", scale);
[scroll addSubview:image];
scroll.minimumZoomScale = scale;
scroll.maximumZoomScale = 1.0;
scroll.delegate = self;
[scroll setZoomScale:scroll.minimumZoomScale];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[super dealloc];
}
- (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.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return image;
}
#end
thx for way
You really need to look at Apple's PhotoViewer sample and the WWDC'10 and '11 videos about ScrollViews: they are explaining in details (with this very example of a photoviewer scrolling and zooming) how to implement it:
How to recycle memory so that your memory footprint is drastically reduced (very important for fluidity)
How to handle both scrolling in one view and zooming in the other
If needed, how to do image tiling to optimize memory when zooming (only useful if you tiling is precomputed, so if you have images in your bundle anyway)
This is very interesting tutorials and videos and really worth reading/viewing.
https://github.com/doubleencore/KTPhotoBrowser
find above attached link get source code for photo gallery .....
Is there something that I need to remember when using the windows-based template? Because I'm unclear as to why the tabs are showing up but nothing in the views are showing up.
Could you help? Because I've been searching through previous questions for a few hours now and I still haven't found anything to clear this up.
AnotherMadeUpAppDelegate.h
#import <UIKit/UIKit.h>
#import "AnotherMadeUpViewController.h"
#interface AnotherMadeUpAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
AnotherMadeUpAppDelegate.m
#import "AnotherMadeUpAppDelegate.h"
#implementation AnotherMadeUpAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIViewController *vc1 = [[UIViewController alloc] init];
UIViewController *vc2 = [[UIViewController alloc] init];
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:vc1, vc2, vc3, nil];
[vc1 release];
[vc2 release];
[vc3 release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
...
#end
AnotherMadeUpViewController.h
#import <UIKit/UIKit.h>
#interface AnotherMadeUpViewController : UIViewController<UIScrollViewDelegate>
{
IBOutlet UIPageControl *pageControl;
IBOutlet UIScrollView *scroller;
IBOutlet UILabel *label;
}
#property (nonatomic,retain)IBOutlet UIPageControl *pageControl;
#property (nonatomic,retain)IBOutlet UIScrollView *scroller;
#property (nonatomic,retain)IBOutlet UILabel *label;
-(IBAction)clickPageControl:(id)sender;
#end
AnotherMadeUpViewController.m
#import "AnotherMadeUpViewController.h"
#implementation AnotherMadeUpViewController
#synthesize pageControl,scroller,label;
-(IBAction)clickPageControl:(id)sender
{
int page=pageControl.currentPage;
CGRect frame=scroller.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scroller scrollRectToVisible:frame animated:YES];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int page = scrollView.contentOffset.x/scrollView.frame.size.width;
pageControl.currentPage=page;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
[label release];
}
- (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];
scroller.pagingEnabled=YES;
CGFloat labelOriginX = label.frame.origin.x;
CGFloat labelOriginY = label.frame.origin.y;
CGFloat scrollWidth = 0;
int pageNumber = 0;
for (int i=0; i<9; i++)
{
CGRect rect = label.frame;
rect.size.height = label.frame.size.height;
rect.size.width = label.frame.size.width;
rect.origin.x = labelOriginX + scrollWidth;
rect.origin.y = labelOriginY;
label.frame = rect;
label.text = [NSString stringWithFormat:#"%d", pageNumber];
label.textColor = [UIColor redColor];
[scroller addSubview:label];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
scroller.delegate=self;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
pageControl.numberOfPages=9;
pageControl.currentPage=0;
scroller.contentSize=CGSizeMake(pageControl.numberOfPages*self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:scroller];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[label release];
self.label = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Dissecting your viewDidLoad –
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
You seem to be creating a new scroll view instance here but you have declared it as an outlet. If you don't have an outlet then remove the IBOutlet tag for scroller. If you do have one and want to use it then remove the above line. A shorter way of doing it would be,
scroller = [[UIScrollView alloc] initWithFrame:self.view.bounds];
Another thing is that you are creating 10 labels but assigning no frame. To show one of them each in different page,
int pageNumber = 0;
for (int i = 0; i < 10; i++)
{
UILabel *label = [[UILabel alloc] init];
[label sizeToFit];
label.center = CGPointMake (((2 * i + 1) * self.view.frame.size.width) / 2, self.view.frame.size.height / 2);
label.text = [NSString stringWithFormat:#"%d", pageNumber];
[scroller addSubview:label];
[label release];
pageNumber++;
}
and later set the contentSize to show 10 pages,
scroller.contentSize = CGSizeMake(10 * self.view.frame.size.width, self.view.frame.size.height);
The problem is with this line
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] init];
You need to change it to
AnotherMadeUpViewController *vc3 = [[AnotherMadeUpViewController alloc] initWithNibName:#"AnotherMadeUpViewController" bundle:nil];
Then your .xib will get loaded and your outlets will be connected.
And don't forget to connect your outlets to File's owner in IB.
Here is the idea:
The scroll view has several sub views, in this example, A, B, C:
[A][B][C]
Once the user scrolls to C, the view can't scroll anymore, but I want to loop back to A, like this:
[C][A][B]
When the user keeps scrolling to the right, the view keeps filling previous views in at the end. When the user
scrolls to left the view should also have similar behavior,
in order to make the user think that this view is infinitely long:
[A][B][C][A][B][C][A][B][C][A][B][C][A][B][C][A][B][C].....
How can I implement this in actual code? Thank you.
you need to set a delegate method that gets called when the view is scrolled, and then check any view that is more than one screens worth of pixels away from being visible, if it is then reposition the view 3*screen width to the other side.
This is what you want( on iphone 7 plus). This is pure code UI, no storyboard.First you need add sub code in your AppDelegate.m.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
ViewController *vc = [ViewController alloc];
self.window.rootViewController = vc;
self.window.backgroundColor = [UIColor redColor];
return YES;
}
Second add sub code in ViewController.m
#interface ViewController ()<UIScrollViewDelegate>
#property (nonatomic, strong) UIScrollView *readCannelScrollView;
#property (nonatomic, strong) UIImageView *pageOneView;
#property (nonatomic, strong) UIImageView *pageTwoView;
#property (nonatomic, strong) UIImageView *pageThreeView;
#end
#implementation ViewController
- (void)dealloc
{
_readCannelScrollView = nil;
_pageOneView = nil;
_pageTwoView = nil;
_pageThreeView = nil;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//容器的属性设置
self.readCannelScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.readCannelScrollView];
CGSize size = self.readCannelScrollView.contentSize;
size.width = 414*3;
self.readCannelScrollView.contentSize = size;
self.readCannelScrollView.pagingEnabled = YES;
self.readCannelScrollView.showsHorizontalScrollIndicator = NO;
self.readCannelScrollView.delegate = self;
self.readCannelScrollView.contentOffset = CGPointMake(0, 0);
//end
//添加页面1
self.pageOneView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 414, self.view.bounds.size.height)];
self.pageOneView.backgroundColor = [UIColor lightGrayColor];
self.pageOneView.image = [UIImage imageNamed:#"1"];
// self.pageOneView.font = [UIFont systemFontOfSize:80];
// self.pageOneView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageOneView];
//添加页面2
self.pageTwoView = [[UIImageView alloc] initWithFrame:CGRectMake(828, 0, 414, self.view.bounds.size.height)];
self.pageTwoView.backgroundColor = [UIColor greenColor];
self.pageTwoView.image = [UIImage imageNamed:#"2"];
// self.pageTwoView.font = [UIFont systemFontOfSize:80];
// self.pageTwoView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageTwoView];
//添加页面3
self.pageThreeView = [[UIImageView alloc] initWithFrame:CGRectMake(828, 0, 414, self.view.bounds.size.height)];
self.pageThreeView.backgroundColor = [UIColor grayColor];
self.pageThreeView.image = [UIImage imageNamed:#"3"];
// self.pageThreeView.font = [UIFont systemFontOfSize:80];
// self.pageThreeView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageThreeView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark -
#pragma mark - scroll delegate
- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"scrollView.contentOffset.x=%f",scrollView.contentOffset.x);
CGFloat pageWidth = scrollView.frame.size.width;
int currentPage = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1;
if (currentPage == 0)
{
UIImageView *tmpTxtView = self.pageThreeView;
self.pageThreeView = self.pageTwoView;
self.pageTwoView = self.pageOneView;
self.pageOneView = tmpTxtView;
}
if (currentPage == 2)
{
//换指针
UIImageView *tmpTxtView = self.pageOneView;
self.pageOneView = self.pageTwoView;
self.pageTwoView = self.pageThreeView;
self.pageThreeView = tmpTxtView;
}
//恢复原位
self.pageOneView.frame = (CGRect){0,0,self.pageOneView.frame.size};
self.pageTwoView.frame = (CGRect){414,0,self.pageTwoView.frame.size};
self.pageThreeView.frame = (CGRect){828,0,self.pageThreeView.frame.size};
self.readCannelScrollView.contentOffset = CGPointMake(414, 0);
}
#end
If you are satisfied with my answer give me a star.I need reputation.
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.