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;
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 have a UIView subclass of a table's header view, is it possible to get the table view from my header view subclass using viewWithTag:? I tried below methods but still get nothing:
my method 1:
UIView *tv = (UIView *)[self.superview viewWithTag:11];
my method 2:
UITableView *tv = (UITableView *)[self.superview viewWithTag:11];
Thanks.
The best solution is to walk the view's superview hierarchy until you get to the table view. This approach will work regardless of the underlying table view structure.
UIView *view = self.superview;
UITableView *tv = nil;
while (view) {
if ([view isKindOfClass:[UITableView class]]) {
tv = (UITableView *)view;
break;
}
view = view.superview;
}
if (tv) {
// found the table view. Do something with it
}
Create your UITableView:
TableHeaderView *v = [[TableHeaderView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
_tableView.tableHeaderView = v;
// I think you miss this line
_tableView.tag = 101;
_tableView.backgroundColor = [UIColor redColor];
NSLog(#"%#",_tableView.backgroundColor);
// value: UIDeviceRGBColorSpace 1 0 0 1
In your TableHeaderView:
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// just example to get super class
[self performSelector:#selector(doSomething) withObject:nil afterDelay:5];
}
return self;
}
- (void) doSomething
{
UITableView *tb = (UITableView*) [self.superview viewWithTag:101];
NSLog(#"%#",tb.backgroundColor);
// value: after:UIDeviceRGBColorSpace 1 0 0 1
}
When i press the back button. the iCarousel is still shows up for 1 second.why is this happening and how to stop this.I have used storyboard to create a iCarosel view..
- (void)viewDidUnload
{
[super viewDidUnload];
self.carousel = nil;
}
- (void)dealloc
{
carousel.delegate = nil;
carousel.dataSource = nil;
}
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
return [idOfAllWords 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, 250.0f, 250.0f)];
((UIImageView *)view).image = [UIImage imageNamed:#"page.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [label.font fontWithSize:50];
label.tag = 1;
[view addSubview:label];
}
else
{
label = (UILabel *)[view viewWithTag:1];
}
Words *word=nil;
word=idOfAllWords[index];
label.text =word.Name;
return view;
}
Hiding and unhiding is not the solution. What you need is just one line:
yourCarousel.clipsToBounds = YES;
I actually tried to reproduce your problem and did see that the carousel view stays for a second when 'pop' or back button press happens. This particularly happens when you the carousel is swiped and then the back button pressed. As a workaround, I was able to fix it by setting the iCarousel hidden in the viewWillDisappear method.
- (void)viewWillDisappear:(BOOL)animated
{
[YOUR_CAROUSEL_NAME setHidden:YES]; //This sets the carousel to be hidden when you press Back button
}
If this looks to be hidden suddenly, you can perhaps try setting the alpha to 0.0 inside an animation block. Something like this:
- (void)viewWillDisappear:(BOOL)animated
{
//[YOUR_CAROUSEL_NAME setHidden:YES];
[UIView animateWithDuration:0.2f animations:^{
[YOUR_CAROUSEL_NAME setAlpha:0.0f]; //This makes the carousel hide smoothly
}];
}
Hope this helps!
I've created 5 UIView dynamically, which consists of one UILabel and one UIButton each. When I click button, the UIView will setHidden. But it works only on one not other four uiviews.
#interface ViewController : UIViewController
{
NSMutableArray *newViews;
}
#property(nonatomic,retain)IBOutlet UILabel *welcome;
#property(nonatomic,retain)CustomView *custom;
-(void)buttonPressed:(UIButton *)sender;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *name=#"string of length";
int length=[name length];
newViews = [NSMutableArray array];
NSMutableArray *myArray = [NSMutableArray arrayWithObjects:#"cricket", #"golf",#"wrestling", #"FootBall is good game", nil];
int yAxis=44;
int lengthOfArray=[myArray count];
for(int a=0; a<=lengthOfArray; a++){
self.custom= [[CustomView alloc]initWithFrame:CGRectMake(20, yAxis, 100, 44)];
yAxis=yAxis+50;
NSLog(#"yaxis is %i",yAxis);
self.custom.tag=200+a;
[newViews addObject:self.custom];
self.custom.Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, length+70, 30)];
self.custom.button=[[UIButton alloc]initWithFrame:CGRectMake(85,10,12,10)];
UIImage *btnImage = [UIImage imageNamed:#"button_droparrow.png"];
[self.custom.button setImage:btnImage forState:UIControlStateNormal];
[self.custom.button addTarget:self action:#selector(buttonPressed:)forControlEvents:UIControlEventTouchDown];
self.custom.button.tag=self.custom.button.tag+a;
self.custom.backgroundColor=[UIColor greenColor];
custom.Label.text=#"welcome";
custom.Label.backgroundColor = [UIColor yellowColor];
[self.custom addSubview:self.custom.button];
[self.custom addSubview:custom.Label];
[self.view addSubview:self.custom];
}
[self.custom.button addTarget:self action:#selector(buttonPressed:)forControlEvents:UIControlEventTouchDown];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)buttonPressed:(UIButton *)sender
{
[self.custom setHidden:YES];
}
#end
Kindly help me. I am new in iOS development. I need here to create UIView with differrnt reference and that reference assign to UIButton to close that particular UIView but I could not get result out.
You could use UISegmentedControl along with number of xib for each UIView.
In each UIView you can place the required UIControls and link the same.
In the delegate method of SegmentedControl 'indexDidChangeForSegmentedControl:(UISegmentedControl *)sender' on each index remove the earlier UIView and add the required UIView.
In the main header file add the IBOutlet for each UIView
#property (nonatomic, weak) IBOutlet UIView *view1;
#property (nonatomic, weak) IBOutlet UIView *view2;
In .m file in the delegate method 'indexDidChangeForSegmentedControl'
- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender {
NSUInteger index = sender.selectedSegmentIndex;
if (UISegmentedControlNoSegment != index) {
if (currentIndex == index) {
return;
}
currentIndex = index;
switch (index) {
case 0:
{
[self.previousView removeFromSuperview];
[self.view addSubview:view1];
self.previousView = view1;
}
break;
case 1:
{
[self.previousView removeFromSuperview];
[self.view addSubview:view2];
self.previousView = view2;
}
break;
}
}
}
Hope this helps.
If you want to use properties, you will have to make a property for each view. Instead, if you want to create them dynamicaly you could store the references to each view in an array.
The next you should know/do is to add a tag to each button. A tag is just a number, which in this case should reference to its position in the Array.
Then based on the button tag (that you can retrieve from the sender) you can retrieve the proper view/button from the array and change the Hidden property on it.
For example (pseudo code/this wont compile):
Creating the views array
#property (nonatomic, strong) NSMutableArray *views;
In View did load create the views
views = [[NSMutableArray alloc] init];
int nrOfViews = 5;
for(int a=0; a<=nrOfViews; a++){
UIView *view = create UIView here.
UIButton *button = create button here.
[view addSubView: button];
[button setTag: a];
[views addObject: view];
}
reference to the view through the pointer retained in the array, find the right one based on the button tag.
-(void)buttonPressed:(UIButton *)sender
{
UIView *view = [views objectAtIndex: sender.tag]; //using the button tag to identify the right view.
[view setHidden: yes];
}
Try something like this:
- (void) buttonPressed: (UIButton*) sender
{
UIView* view = sender.superview;
view.hidden = YES;
}
You need to make some changes as follows
#property(nonatomic,strong)IBOutlet UILabel *welcome; // new arc code
#property(nonatomic,strong)UIView *custom; // new arc code
self.custom = [[UIView alloc]initWithFrame:CGRectMake(20, yAxis, 100, 44)];
I'm trying to create a scrollview with an array of clickable UIImageView's. My goal is that when an ImageView is clicked, it returns which position in the array it occupies. The problem is that i don't know how to "catch" the position's number. How do I do that?
So far I have:
- (IBAction)respondToTapGesture:(UITapGestureRecognizer *)recognizer {
NSLog(#"%#",)//here is where i want to return the element's position.
}
-(void) preenchemenu {
[menu setContentSize:CGSizeMake(400, 91)];
int x=0;
imagensmenu=[NSArray arrayWithObjects:[UIImage imageNamed:#"teste2.tiff"],[UIImage imageNamed:#"teste2.tiff"], nil];
for (int i = 0; i <3; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,0 , 90, 91)];
x=x+90;
imageView.image = [imagensmenu objectAtIndex:i];
imageView.tag = 1000+ i;
imageView.userInteractionEnabled = YES;
imageView.multipleTouchEnabled = YES;
UITapGestureRecognizer *tapRecognizermenu = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(respondToTapGesture:)];
tapRecognizermenu.numberOfTapsRequired = 1;
[imageView addGestureRecognizer:tapRecognizermenu];
[menu addSubview:imageView];
}
}
You can create an array to hold you imageViews and then find the position of your imageView in this array when it is tapped.
Add a property for this
#property (nonatomic, strong) NSMutableArray *imageViews;
initialise it in init
- (id)init...
{
self = [super init...
if (self) {
_imageViews = [NSMutableArray array];
}
return self;
}
Then amend your current method slightly to also add the imageViews to this array as well as a subview of the menu
[self.imageViews addObject:imageView];
[menu addSubview:imageView];
Then in your gesture recognizer call back you can do
- (void)respondToTapGesture:(id)sender;
{
UIView *view = [sender view];
NSLog(#"%d", [self.imageViews indexOfObject:view]);
}
Just find the index by
- (IBAction)respondToTapGesture:(UITapGestureRecognizer *)recognizer
{
UIView *view = recognizer.view;
NSLog(#"Index of image in array is %d", view.tag-1000);
}