Tableview with custom UIView , adding labels overlaps - ios

I am trying to implement ibooks bookshelf like functionality and I use GSBookShelf which is pretty simple and straight forward, it adds button as cells and it works great.
I want to add some labels to each button, I succeed but once in a while lets say 2 out of 5 times labels overlaps from previous buttons label.
normally like this
Sometime this happens:
Code:
- (UIView *)bookShelfView:(GSBookShelfView *)bookShelfView bookViewAtIndex:(NSInteger)index {
NSDictionary *currentArticle = [_bookArray objectAtIndex:index];
static NSString *identifier = #"bookView";
MyBookView *bookView = (MyBookView *)[bookShelfView dequeueReuseableBookViewWithIdentifier:identifier];
if (bookView == nil) {
bookView = [[MyBookView alloc] initWithFrame:CGRectZero];
bookView.reuseIdentifier = identifier;
[bookView addTarget:self action:#selector(bookViewClicked:) forControlEvents:UIControlEventTouchUpInside];
}
[bookView setIndex:index];
[bookView setSelected:[(NSNumber *)[_bookStatus objectAtIndex:index] intValue]];
//[bookView setFileName:[currentArticle objectForKey:#"name"] ];
//[bookView setFileName:[currentArticle objectForKey:#"name"] :index];
UIImage *image = nil;
image = [self returnCellImagefor:[currentArticle objectForKey:#"imagename"]];
[bookView setBackgroundImage:image forState:UIControlStateNormal];
UILabel *_fileLabel=nil;
_fileLabel =[[UILabel alloc] initWithFrame:CGRectMake(0, 180, 200, 46)];
_fileLabel.text=[currentArticle objectForKey:#"name"];
_fileLabel.textColor=[UIColor whiteColor];
_fileLabel.backgroundColor=[UIColor clearColor];
_fileLabel.font = [UIFont fontWithName:#"Gill Sans" size:16];
//_fileLabel.textAlignment=UITextAlignmentCenter;
_fileLabel.textAlignment = NSTextAlignmentCenter;
_fileLabel.numberOfLines=0;
_fileLabel.lineBreakMode = UILineBreakModeWordWrap;
[_fileLabel sizeToFit];
[bookView addSubview:_fileLabel];
return bookView;
}
Images are good they never overlap but label does it sometimes.
Any idea why this is happening?

Where did you put bookShelfView function at? Show your TableView code. I bet the problem you have is that when you scroll down in table bookShelfView is being called again. Your label is being created twice for two different values.
That's the only way you see that overlap happening, this is being initiated over and over again
_fileLabel =[[UILabel alloc] initWithFrame:CGRectMake(0, 180, 200, 46)];
I would check your TableView Code. I had asked a similar question before. (not exact). Check it out UITableView and UILabel repeating

Related

objective c How to access and change dynamically created button background color in a uiscrollview

As you can see in the screenshot I have created multiple buttons dynamically in a UI scroll view. Every button actually holds a date action upon which specific events to that date loads into table. UI Scroll view is global element in the code which can be accessed by any method in the controller.
What I wanted now is access a button (when someone chooses a date to see events on that date) in that scrollview and change its background color. For your convenience I have added the whole code for date and scrollview. Please also note that data are loading from remote server.
Link to the screenshot is as follows
Please forgive me if you see anything wrong in typing. This is my first question in stack.
luckyDateScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(22, 2, lucky_screen_width-45, 23)];
luckyDateScrollView.showsHorizontalScrollIndicator = NO;
CGFloat paperWidth = 50;
int numberOfPapers = [dateRanges count];
for (int i=0; i<[dateRanges count]; i++) {
//NSLog(#"%d: %#", i, dateRange[i]);
//php like exploding with separator |
NSArray *dateString = [dateRanges[i] componentsSeparatedByString:#"|"];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake( 5+ (paperWidth+4) * i , 0, paperWidth, luckyDateScrollView.bounds.size.height)];
btn.titleLabel.font = [UIFont fontWithName:#"Arial" size:11.0f];
[btn setTitle: [NSString stringWithFormat:#"%#",dateString[0]] forState:UIControlStateNormal];
//dateResendButton
[btn setTag:i];
[btn addTarget:self
action:#selector(byDateFilterButton:)
forControlEvents:UIControlEventTouchUpInside];
if([today isEqualToString:dateString[1]]){
[GlobalMethods makeRoundedView:btn WithColorString:#"#ffffff" BGColorString:#"#004D00"];
}else{
[GlobalMethods makeRoundedView:btn WithColorString:#"#ffffff" BGColorString:GlobalVariables.initGV.BlackColor];
}
//[GlobalMethods makeRoundedView:btn WithColorString:#"#ffffff" BGColorString:#"#FF0000"];
[luckyDateScrollView addSubview:btn];
}
contentSize = CGSizeMake( 10 + (paperWidth+4) * numberOfPapers, luckyDateScrollView.bounds.size.height);
luckyDateScrollView.contentSize = contentSize;
// [GlobalMethods makeRoundedView:aScrollView WithColorString:#"#ffffff" BGColorString:GlobalVariables.initGV.BlackColor];
[dateUIView addSubview:luckyDateScrollView];
luckyDateBtnLeftScroll = [[UIButton alloc] initWithFrame:CGRectMake(5, 2, 20, 23)];
[luckyDateBtnLeftScroll setBackgroundImage:[UIImage imageNamed:#"arrow_g_icon_left"] forState:UIControlStateNormal];
[luckyDateBtnLeftScroll addTarget:self action:#selector(dateSetScrollToLeft:) forControlEvents:UIControlEventTouchUpInside];
[dateUIView addSubview:luckyDateBtnLeftScroll];
luckyDateBtnRightScroll = [[UIButton alloc] initWithFrame:CGRectMake(lucky_screen_width-25, 2, 20, 23)];
[luckyDateBtnRightScroll setBackgroundImage:[UIImage imageNamed:#"arrow_g_icon"] forState:UIControlStateNormal];
[luckyDateBtnRightScroll addTarget:self action:#selector(dateSetScrollToRight:) forControlEvents:UIControlEventTouchUpInside];
[dateUIView addSubview:luckyDateBtnRightScroll];
//ViewCollapse.backgroundColor = [UIColor colorWithCGColor: #"#FFD80D"];
If I understand your question correctly you can simply change the background of your button in the byDateFilterButton: method. It should have a sender parameter which would be the button in question.
If you also need to change the background of the other buttons back to normal, you need to keep a reference to them, probably in an array (or dictionary - if you have many buttons and need fast access).
I modified byDateFilterButton method in a following way. Thanks to this SO post Access all buttons in uiscollview
for (id obj in luckyDateScrollView.subviews) {
NSString *classStr = NSStringFromClass([obj class]);
if ([classStr isEqualToString:#"UIButton"]) {
UIButton *button = (UIButton*)obj; //NSLog(#"buttonn tag %ld",(long)button.tag);
if(sender.tag == button.tag){ // currently selected button
[GlobalMethods makeRoundedView:button WithColorString:#"#ffffff" BGColorString:#"#555454"];
}
else{ // the rest of buttons
[GlobalMethods makeRoundedView:button WithColorString:#"#ffffff" BGColorString:GlobalVariables.initGV.BlackColor];
}
}
}

Get click of imageview(added dynamically) within a row of uitableview in ios

I have a tableview whose rows are dynamic and each row have n numbers of imageviews as it is in the screenshot attached
Now what I want is to know which imageview I have clicked.
NOTE : imageview is added dynamically to one view and that view is added to scrollview so that it can scroll horizontally.
And there are n numbers of row in a tableview.
EDIT:
I tried adding simple button as well above the image view just to try out if that clicks but its click also didn't work.
I tried the solution of Gesture as well but that also didn't work
CODE:
-(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *strrowId ;
UITableViewCell *cell = [_tblviewScroll1 dequeueReusableCellWithIdentifier:#"cellOne"];
// create and add labels to the contentView
[cell.contentView setBackgroundColor:[UIColor colorWithRed:231.0/255.0 green:231.0/255.0 blue:231.0/255.0 alpha:1.0]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// cell.contentView.userInteractionEnabled=NO;
scrollView1 = (UIScrollView*)[cell.contentView viewWithTag:3];
[scrollView1 setShowsVerticalScrollIndicator:NO];
scrollView1.delegate = self;
NSArray* subviews1 = [scrollView1 subviews];
for (UIView* subview in subviews1) {
[subview removeFromSuperview];
}
if (scrollView1.contentOffset.y > 0 || scrollView1.contentOffset.y < 0 )
scrollView1.contentOffset = CGPointMake(scrollView1.contentOffset.x, 0);
[scrollView1 setBackgroundColor:[UIColor colorWithRed:231.0/255.0 green:231.0/255.0 blue:231.0/255.0 alpha:1.0]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleBlack;
scrollView1.clipsToBounds = YES
scrollView1.scrollEnabled = YES;
for (int i = 0; i <mutSubTitle.count; i++)
{
NSString *ids = #"";
UIView *viewvertically1;
viewvertically1=[[UIView alloc]init];
viewvertically1.tag = (i+1);
[viewvertically1 setUserInteractionEnabled:YES];
[viewvertically1 setBackgroundColor:[UIColor whiteColor]];
//Displaying image
NSString *strImgUrl = #"https://img.xxxx.com/";
NSString *strimge=[mutSubImag objectAtIndex:i];
strImgUrl = [strImgUrl stringByAppendingString:strimge];
NSURL *url = strImgUrl;
UIImage *image = [UIImage imageNamed:url];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame= CGRectMake(0, 10, 170, 110);
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[imageView setUserInteractionEnabled:YES];
// images with Lazy Loading
[imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:#"Placeholder.png"]];
UITapGestureRecognizer *imgTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(gestureTapEvent:)];
imgTapGesture.numberOfTouchesRequired = 1;
[imageView addGestureRecognizer:imgTapGesture];
[viewvertically1 addSubview:imageView];
[viewvertically1 addSubview:lblDesc];
[scrollView1 addSubview:viewvertically1];
//[cell bringSubviewToFront:scrollView1];
}
return cell;
}
In your cellForRowAtIndexPath method add the UITapGestureRecognizer for your Concept
// by default the imageview userInteraction is disable you need to manually enable
cell.yourimageView.userInteractionEnabled = YES;
// the following line used for assign the different tags for eachImage
cell.yourimageView.tag = indexPath.row;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(ImageTapped:)];
tap.numberOfTapsRequired = 1;
[cell.yourimageView addGestureRecognizer:tap];
finally need to check which imageView was clicked, check the flag in selector method
-(void)ImageTapped :(UITapGestureRecognizer *) gesture
{
// you can get tag in which image is selected
NSLog(#"Tag = %d", gesture.view.tag);
}
Try giving a button instead of image view added to a view. Assign the image to button's backgroundImageView. You can then give actions for the buttons
Use UIButton as #Arun says or the imageview ur using currently add button on Image with clear background color and add tag to that button and use that click action.

Accessing UILabel created on run time

I have created UILabel (lblCount) and UIButton (btnAdd) on a UIButton (Add Item Button)'s action method. The new UILabel and UIButton is added to scrollview. The UILabel (lblCount) shows count of UIButton (btnAdd) tapped. Here, addBtnClickCount is an integer which counts the number of click.
UILabel * lblCount = [[UILabel alloc] initWithFrame:CGRectMake( 50, 100*addBtnClickCount, 25, 25)];
lblCount.text = [NSString stringWithFormat:#"%d",count];
lblCount.tag = addBtnClickCount;
lblCount.textColor = [UIColor whiteColor];
lblCount.textAlignment = NSTextAlignmentCenter;
[self.scrollView addSubview:lblCount];
addBtnClickCount = addBtnClickCount+1;
There will be multiple label (lblCount) and button (btnAdd) when user taps Add Item Button. I want to access particular label for particular add button and display the count.
You have already set tag on your label. Create a mutable array labelArray and add label to it. To access the particular label do following code on add button's action.
-(void)addItem:(UIButton*)button{
UILabel* lblShowCount = [_labelArray objectAtIndex:[button tag]];
lblShowCount.text = [NSString stringWithFormat:#"%d", [lblShowCount.text integerValue]+1];
}
Here i understand that #Hem Poudyal, know's that with help of viewWithTag.he will get output. but don't know how to achieved that. so i am describing over here.
Step 1: Here i am adding UILabel and UIButton to self.view instead of UIScrollView. i hope you can convert it as UIScrollView. here i applied some relation between UILabel tag and UIButton tag. that you can see in below code.
for (int i=0; i<10; i++) {
UILabel * lblCount = [[UILabel alloc] initWithFrame:CGRectMake( 50, (i*50)+((i+1)*5), 100, 50)];
lblCount.text = [NSString stringWithFormat:#"%d",0];
lblCount.tag = [[NSString stringWithFormat:#"%d%d",i,i] integerValue];
lblCount.backgroundColor = [UIColor yellowColor];
lblCount.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:lblCount];
UIButton* btnTemp = [UIButton buttonWithType:UIButtonTypeCustom];
btnTemp.tag = i;
btnTemp.backgroundColor = [UIColor redColor];
[btnTemp addTarget:self action:#selector(btnTempClick:) forControlEvents:UIControlEventTouchUpInside];
btnTemp.frame = CGRectMake( 150, (i*50)+((i+1)*5), 100, 50);
[btnTemp setTitle:[NSString stringWithFormat:#"Button : %d",i] forState:UIControlStateNormal];
[self.view addSubview:btnTemp];
}
Step 2: In UIButton selector method, Do the following things.
-(IBAction)btnTempClick:(id)sender{
UIButton* btnInner = sender;
NSInteger lblTagbaseOnButtonTag = [[NSString stringWithFormat:#"%ld%ld",btnInner.tag,btnInner.tag] integerValue];
UILabel* lblReceived = (UILabel*)[self.view viewWithTag:lblTagbaseOnButtonTag];
lblReceived.text = [NSString stringWithFormat:#"%ld",[lblReceived.text integerValue]+1];
}
And Output is :
You should have an array that you add the labels and buttons too (this could be one array containing a dictionary or custom class or multiple arrays). Now, when a button is tapped you can find where it is in the array and get the corresponding label to update.
The cheat way is to set the tag of the buttons and labels so you can find one from the other using viewWithTag:.
You need to set unique tag value while creating the labels and buttons and by using viewWithTag: you can access the respective ui container.

Switching UISwitch on/off by pressing on UILabel

I've got this method were it displays UILabels and UISwitches right next to them. I want the UISwitch to be switched on and off by pressing on a label as well. I have tagged the switches but I don't know what to do next.. Any help would much appreciated. Thanks!
while (i < numberOfAnswers) {
UILabel *answerLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, y+spaceBetweenAnswers, 240, 30)];
answerLabel.text = [NSString stringWithFormat:#"%# (%#)", questionBank[randomQuestionNumber][1][i][0],questionBank[randomQuestionNumber][1][i][1]];
answerLabel.font = [UIFont systemFontOfSize:15];
answerLabel.textColor = [UIColor darkGrayColor];
answerLabel.numberOfLines=0;
[answerLabel sizeToFit];
[_answerView addSubview:answerLabel];
answerHeight = answerLabel.frame.size.height + spaceBetweenAnswers;
UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(10, y+spaceBetweenAnswers-5, 0, 30)];
mySwitch.transform = CGAffineTransformMakeScale(0.75, 0.75);
if ([questionBank[randomQuestionNumber][1][i][1] isEqual:#"0"]) {
[mySwitch addTarget:self action:#selector(wrongAnswer:) forControlEvents:UIControlEventValueChanged];
} else {
}
mySwitch.tag = i;
[_answerView addSubview:mySwitch];
}
Use a UIButton instead of a UILabel and set an IBAction on it. You can style the button to look exactly like the label. Your IBAction method should look something like this:
- (void)buttonPressed:(UIButton *)sender
{
//Get the view by tag
UISwitch *mySwitch = (UISwitch *)[self.view viewWithTag:yourTag];
[mySwitch.setOn:![mySwitch isOn]];
}
Edit
As mentioned, since you're building the UIButtons in code, you need to add the target to the button to get the button click. Add the action as such:
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
Add a tap gesture recognizer to each label. When it is tapped, you can get the label from the gesture (view). Now you just need to get the switch to update.
You could add a tag to the label which is 1000 + i, then a simple subtraction will give you the switch tag that you need to find.
You could tag the labels and use the tag as the index into an array or switches (possibly IBOutletCollection).
You can do something like this.
UISwitch* mySwitch = [[UISwitch alloc]init];
[self addSubview:mySwitch];
UIButton* switchLabelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
switchLabelBtn.frame = CGRectMake(0, 0, 80, 40);
[switchLabelBtn addTarget:self action:#selector(switchLabelbtnTapped:) forControlEvents:UIControlEventTouchUpInside];
[switchLabelBtn.layer setValue:mySwitch forKey:#"Switch"];
[self addSubview:switchLabelBtn];
- (void)switchLabelbtnTapped:(UIButton*)sender
{
UISwitch* mySwitch = [sender.layer valueForKey:#"Switch"];
mySwitch.on = ![mySwitch isOn];
}

Changing through different pieces of text in UITextView/UILabel using next & previous UIButton

Let's say I have 5 pieces of text. I want to use a UITextView or UILabel to display it. I have a Next and Previous button to help me cycle it through. What's the best way to solve this problem?
NSString *text1 = #"Hello World 1"
NSString *text2 = #"Hello World 2"
NSString *text3 = #"Hello World 3"
NSString *text4 = #"Hello World 4"
NSString *text5 = #"Hello World 5"
this solution might be good
in .h file
UIButton *nextButton;
UIButton *backButton;
UILabel *textLabel;
NSArray *textStr;
int counter;
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
counter=0;
textStr = [[NSArray alloc] initWithObjects:#"Today is rainy", #"Today is sunnt", #"Today is bright", #"Today is gloomy",
#"Today is beautifyl", nil];
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, 200, 200)];
textLabel.text= [NSString stringWithFormat:#"%#", [textStr objectAtIndex:0]];
[self.view addSubview:textLabel];
nextButton= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[nextButton addTarget:self
action:#selector(btnClicked:)
forControlEvents:UIControlEventTouchDown];
nextButton.tag=1;
[nextButton setTitle:#"Next" forState:UIControlStateNormal];
nextButton.frame = CGRectMake(120.0, 150, 80, 40.0);
[self.view addSubview:nextButton];
backButton= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[backButton addTarget:self
action:#selector(btnClicked:)
forControlEvents:UIControlEventTouchDown];
backButton.tag=2;
[backButton setTitle:#"Previous" forState:UIControlStateNormal];
backButton.frame = CGRectMake(30.0, 150, 80.0, 40.0);
[self.view addSubview:backButton];
}
-(void)btnClicked:(UIButton*)btn{
if (btn.tag==1) {
NSLog(#"%i", [textStr count]);
if (counter<[textStr count]-1) {
counter++;
NSLog(#"%i", counter);
textLabel.text= [NSString stringWithFormat:#"%#", [textStr objectAtIndex:counter]];
}
}
else{
if (counter>1) {
counter--;
textLabel.text= [NSString stringWithFormat:#"%#", [textStr objectAtIndex:counter]];
}
}
}
Here is the basic idea, as the implementation is trivial I won't post the exact code as it will beneficial to learn on your own.
1.Add all your strings to an NSArray.
2.Add two buttons to your view with InterfaceBuilder and link to your code.
3.Add a label to your view and link to your code.
4.Create an int property and call it counter.
5.When the users presses "next" we want to:
5.1 Increase the counter by 1.
5.2 Check to make sure the counter is higher than our array length.
5.3 If counter > array length then we can set it back to 0 to it loops around.
5.4 if counter <= array length then we do nothing.
5.5 grab the string out of the array at the counter index
5.6 set our label we created in #3 text to the retrieved string.
6.When the user presses "previous" we want to:
6.1 Decrease the counter by 1.
6.2 Check to make sure the counter is >= 0
6.3 If counter < 0 then we can set it equal to our array length so it loops
6.4 if counter <= 0 length then we do nothing.
6.5 grab the string out of the array at the counter index
6.6 set our label we created in #3 text to the retrieved string.

Resources