My code is below
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIImageView *imgView = nil;
if (view == nil)
{
NSLog(#"no is %i",index);
view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 255, 255)] autorelease];
imgView = [[[UIImageView alloc] initWithImage:[ImagesCFArray objectAtIndex:index]] autorelease];
[view addSubview:imgView];
}
else
{
}
return view;
}
ImagesCfArray contains the images to be displayed. 0th index image overlapping with other images when carousel moves or scrolls. Please give me solution for this.
Can you show your itemWidth implementation? Does it return more than 255?
You might want to tell the subview to clip to its bounds:
imgView.clipToBounds = YES;
And also, perhaps use a fill for the image:
imgView.contentMode = UIViewContentModeScaleAspectFit;
Related
I have 2 labels.
First label, named "label" is placed inside every view within the carousel. The string/text of the label is the view's index.
label.text = [[items1 objectAtIndex:index] stringValue];
I also have a second label (outside the carousel) named "outsideLabel".
I want the outsideLabel's string/text to be the view's index aswell (always the view being in front of the carousel).
outsideLabel.text = [[items1 objectAtIndex:index] stringValue];
Somehow I am doing it wrong and wonder how I shall code this in order to show the proper number in outsideLabel's string/text (always the view being in front). The code somewhat shows the correct numbers but get messed up when scrolling backwards in the carousel. The carouseltype is timeMachine.
My current code:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
if (carousel == carousel1)
{
CGRect test = CGRectMake(10, 10, 20, 20);
self.label.frame = test;
}
else {
CGRect test = CGRectMake(50, 40, 40, 40);
self.label.frame = test;
}
[view addSubview:label];
}
else
{
label = [[view subviews] lastObject];
}
if (carousel == carousel1)
{
//items in this array are numbers
outsideLabel.text = [[items1 objectAtIndex:index] stringValue];
label.text = [[items1 objectAtIndex:index] stringValue];
((UIImageView *)view).image = [UIImage imageNamed:[view1background objectAtIndex:index]];
}
else
{
//not relevant....
}
return view;
}
From the code you've provided, it looks like you're not initializing the outsideLabel in the right place. To be safe, you should initialize all your subviews inside the block where you are checking if the view is nil. Another safe convention is to assign tags to all your subviews, so that you can later retrieve them from views that are reused, as in the code below. For easy reference, and to avoid errors, I define constants for these tags at the top of my implementation file, like this:
#define INSIDE_LABEL_TAG 1
#define OUTSIDE_LABEL_TAG 2
This is much safer, since it doesn't depend on the structure of the views, as is the case with your code, where you get the last view:
label = [[view subviews] lastObject];
Try initializing outsideLabel inside that block, and use tags. The pattern used in initialization is identical to that used for the subviews of UITableView cells in a UITableViewDataSource delegate:
(UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView
cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
Here is some pseudo code that shows where I would use tags and initialize the outsideLabel:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{
//create new view if no view is available for recycling
if (view == nil)
{
//Configure the view
...
/* Initialize views for all carousels */
//Initialize the insideLabel and set its tag
...
insideLabel.tag = INSIDE_LABEL_TAG;
//Initialize the outsideLabel and set its tag
...
outsideLabel.tag = OUTSIDE_LABEL_TAG;
if (carousel == carousel1)
{
//Do any carousel-specific configurations
}
//Add all subviews initialized in this block
[view addSubview:label];
[view addSubview:outsideLabel];
}
else
{
//Get the subviews from an existing view
insideLabel = (UILabel *)[view viewWithTag:INSIDE_LABEL_TAG];
outsideLabel = (UILabel *)[view viewWithTag:OUTSIDE_LABEL_TAG];
}
if (carousel == carousel1)
{
//Set the values for each subview
} else {
//Other carousels...
}
return view;
}
It looks to me like you want the "time machine" style carousel. I don't see your code setting the carousel type anywhere. Don't you need to set the carousel type?
I'm using iCarousel to display images clicked by the user and are reloaded dynamically into the carousel. The whole setup works perfectly with default values for iCarouselOptionVisibleItems but images start to scale up when the total number of images exceeds 8.
TO try and fix the issue i increased the number of iCarouselOptionVisibleItems to 25 and that temporarily fixed the issue but i know thats not the best solution because the images will still scale after the number exceeds 25. Is there something I'm missing from the documentation that I'm missing?
Here's the code for my icarousel screen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.carousel.delegate = self;
self.carousel.dataSource = self;
_carousel.type = iCarouselTypeCoverFlow2;
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
//return the total number of items in the carousel
return [images count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
//create new view if no view is available for recycling
if (view == nil)
{
//don't do anything specific to the index within
//this `if (view == nil) {...}` statement because the view will be
//recycled and used with other index values later
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
view.contentMode = UIViewContentModeScaleAspectFit;
((UIImageView *)view).image = [UIImage imageWithContentsOfFile:[images objectAtIndex:index]];
}
else
{
//get a reference to the label in the recycled view
view.contentMode = UIViewContentModeScaleAspectFit;
view = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[images objectAtIndex:index]]];
}
return view;
}
- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
if (option == iCarouselOptionSpacing)
{
return value * 1.1f;
}
else if (option == iCarouselOptionVisibleItems)
{
return 25;
}
return value;
}
I am trying to achieve a right to left iCarousel object with a fade on both sides.
So i imported the GtiHub Project into My application, Assigned a UIView to iCarousel...Linked that to an IBOutLet on my MainViewController and passed the Delegate as well as the DataSource just like the UITableViewController.
Though it will not show up and i am unsure of what could be causing this issue.
My iCarousel DataSource is is an NSMutableArray *items; designed like so:
for (int i = 0; i < 100; i++)
{
[_items addObject:#(i)];
}
I am initializing the iCarousel in the ViewDidLoad like below
- (void)viewDidLoad
{
[super viewDidLoad];
//Initialize Carousel
_carousel = [[iCarousel alloc] init];
_carousel.delegate = self;
_carousel.dataSource = self;
//Carousel Testing Data
for (int i = 0; i < 100; i++)
{
[_items addObject:#(i)];
}
//configure carousel
_carousel.type = iCarouselTypeRotary;
}
My Delegate Methods for Carousel are below:
#pragma mark -
#pragma mark iCarousel methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
//return the total number of items in the carousel
return [_items count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.font = [label.font fontWithSize:50];
label.tag = 1;
[view addSubview:label];
}
else
{
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
}
label.text = [_items[index] stringValue];
return view;
}
- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
switch (option)
{
case iCarouselOptionFadeMin:
return -0.2;
case iCarouselOptionFadeMax:
return 0.2;
case iCarouselOptionFadeRange:
return 2.0;
default:
return value;
}
}
Everything from the storyboard seems to be connected and the data should be presenting itself, what is wrong and how can i fix this issue?
Since you have the DataSource array (_items) setup after the view gets loaded:
Make sure that the carousel view in your storyboard does have the IBOutlet to the controller, but NOT the 'Delegate' and 'DataSource' linked to the File's Owner (Controller or view).
Set the _carousel.delegate and _carousel.dataSource to 'self' only After you initialize and update the dataSource array (_items in this case).
Place breakpoints to check whether the iCarousel Datasource and Delegate methods are being called or not.
If the methods are not called, check whether the controller follows the iCarousel protocols like this:
#interface yourViewController : UIViewController <iCarouselDataSource, iCarouselDelegate>
Obviously you'll have to
#import "iCarousel.h"
UPDATE: In your viewDidLoad, you have
_carousel = [[iCarousel alloc] init];
looks like you forgot to set a frame for _carousel and add it as a subView.
To get the imageView reference, try this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
imageView.image = [UIImage imageNamed:#"page.png"];
view = imageView;
I am working on app in which i have to make welcome screen. In that UIPageControl i need to display different 9 subviews. Also need infinite circular scrolling in that. It means after page-9 if i slide than page-1 should appear.
I have tried so much to implement it but never got expected results.
Can anyone help me out to get the best solution for it.
Thanks.
I recommended to use iCarousel for doing this task. I do following changes in to there demo Buttons Demo
.h class
#property (nonatomic, assign) BOOL wrap;
.m class
- (void)viewDidLoad
{
[super viewDidLoad];
_wrap = YES;
//configure carousel
carousel.type = iCarouselTypeLinear;
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return 9;
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 400)];
view.backgroundColor=[UIColor redColor];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [label.font fontWithSize:50];
label.tag = 1;
[view addSubview:label];
}
else
{
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
}
label.text = [NSString stringWithFormat:#"%i", index];
return view;
}
- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
//don't do anything specific to the index within
//this `if (view == nil) {...}` statement because the view will be
//recycled and used with other index values later
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 400.0f)];
view.backgroundColor=[UIColor redColor];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [label.font fontWithSize:50.0f];
label.tag = 1;
[view addSubview:label];
}
else
{
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
}
label.text = (index == 0)? #"[": #"]";
return view;
}
- (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 _wrap;
}
case iCarouselOptionSpacing:
{
//add a bit of spacing between the item views
return value * 1.05f;
}
case iCarouselOptionFadeMax:
{
if (carousel.type == iCarouselTypeCustom)
{
//set opacity based on distance from camera
return 0.0f;
}
return value;
}
default:
{
return value;
}
}
}
- (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);
}
or getting tapped Button index:-
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
{
NSLog(#"Tapped view number: %d", index);
}
it's Output is :-
Here is Attached Demo
I'm using iCarousel library in my small app. I'm getting the image urls via web service and placing those images to the iCarousel library.
First I created a UIView and added iCarousel as respective class to it. Latter set the datasourse and delete gate to same class.
Now everything looks cool and I could see the images but I couldn't swipe the images.
Following is my code.
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
//return the total number of items in the carousel
return [galleryItems count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
{
//NSString *ImageURL = #"YourURLHere";
//NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
//imageView.image = [UIImage imageWithData:imageData];
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
//[((UIImageView *)view) setImageWithURL:[NSURL URLWithString:#"http://www.pizzatower.com/img/icons/Pizza-icon.png"]];
NSURL *imageURL = [[galleryItems objectAtIndex:index] galleryURL];
[((UIImageView *)view) setImageWithURL:imageURL];
view.contentMode = UIViewContentModeScaleAspectFit;
label = [[UILabel alloc] init];
label.backgroundColor = [UIColor clearColor];
label.font = [label.font fontWithSize:20];
label.tag = 1;
// label.contentMode = UIViewContentModeBottom;
// label.frame = CGRectMake(
// self.view.frame.size.width - label.frame.size.width,
// self.view.frame.size.height - label.frame.size.height,
// label.frame.size.width,
// label.frame.size.height );
//label.bounds = view.bounds;
[view addSubview:label];
}
else
{
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
}
//set item label
//remember to always set any properties of your carousel item
//views outside of the `if (view == nil) {...}` check otherwise
//you'll get weird issues with carousel item content appearing
//in the wrong place in the carousel
//label.text = [[galleryItems objectAtIndex:index] galleryDescription];
return view;
}
I've used same code base and it worked in some other project. No idea what am I missing here. Can someone please enlighten me.
You UIView containing the carousel may have userInteractionEnabled set to NO.
Another possibility is that the UIView containing the carousel may be smaller than the carousel and so be blocking interaction. Try setting its background color to see its true size.
I'd suggest delete your nib or the ViewController in your storyboard and re-create it. I had the same issue once and after re-creating it it worked. Make sure you center your UIView when placing it (both horizontally and vertically)