I have some values of UIButtons. Every button I have created dynamically, by this code:
-(void)AddNewTable: (NSString *) tablePic: (NSString *) addedType {
CreatedTable *ct = [[CreatedTable alloc] init];
CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);
NSString * uuidString = (__bridge NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);
CFRelease(newUniqueId);
UIImage *tableImage = [UIImage imageNamed: tablePic];
CGRect frameBtn = CGRectMake(160.0f, 160.0f, tableImage.size.width, tableImage.size.height);
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage: tableImage forState:UIControlStateNormal];
[button setFrame:frameBtn];
[button addTarget:self action:#selector (draggedOut:withEvent::) forControlEvents:UIControlEventTouchDragInside];
[button setTitle: [NSString stringWithFormat:#"%d", tables.count] forState: UIControlStateNormal];
ct.Id = [uuidString lowercaseString];
ct.posX = 160;
ct.posY = 160;
ct.isActive = true;
ct.Index = button.titleLabel.text;
ct.picture = [NSString stringWithFormat:#"tables/%#", tablePic];
ct.type = addedType;
ct.angle = 0.0;
[tables addObject:ct];
[hallView addSubview:button];
}
CreatedTable - is NSObject with string params of created buttons.
As you can see, I'm adding selector for every created button. I can move every button by this selector. Here is it's code:
- (IBAction)draggedOut: (id)sender withEvent: (UIEvent *) event: (NSSet *)touches {
CreatedTable = [tables objectAtIndex: selected.[titleLabel.text intValue]]
UIButton *selected = (UIButton *)sender;
selected.center = [[[event allTouches] anyObject] locationInView:hallView];
ct.posX = selected.center.x;
ct.posY = selected.center.y; // Here I'm changing params in ct.
}
Now I need to realize multi-select (select some value of buttons by tapping on them, to make some king of a group) and after that I need to move this group (all selected buttons) like one single object.
Any suggestions how to realize it?
When the user select multiple buttons one by one , mark them all the selected buttons by changing their background image . Now when the user starts dragging any one of the selected button create all Bigger view (with the clear background color) and add the copies(new buttons look alike the selected buttons) of all the selected buttons and add them on to the bigger view . Now changing position of original button (button getting dragged) , change the position of bigger view . It will give a look and feel like all the selected button are getting dragged . Also as soon as the bigger view dragging is stopped remove all the original selected buttons from the main view .
Hope it will help you.
you could set a different Tag to each buttons in AddNewTable like this:
[button setTag:];
and then in draggedOut you can find it by:
[sender tag]
Do you know, how to control the ScrollView, so they do not repeat. For example I have 5 pictures (like the added figure), they should be viewable from 1-5 and it should stop right after the last picture, at the same time it should be able to scroll back and stop right after the first picture. All in all it should only be able to go from 1-5 without repeating after 5th picture and before 1st.
The problem right now is, that it scroll further after 5th, so it begins from 1st picture again, and the other way around when it scroll back to 1st picture it keep going to 5th and so on.
The code that I used for this is:
"InfinitePagingView" page!.
Disabled scroll:
scrollEnabled = NO;
What I want to know is, if I am able to stop scrolling right after 5th picture, but it should only be enable to do that on the right side. So is there any codes like: "scrollEnable right = NO & scrollEnable left = NO". If not, which code can I use.
Advance thanks
so you want infinite scrolling on the right side, but not on the left? You need to customize the InfinitePagingView, that you are using. Look in the code, especially the method scrollView:didScroll and disable it for the left side.
That is not a default behaviour, so there is not a simple property to set. But don't you think this is a strange behaviour? If you scroll right and go over the 5th picture, than you are at the 1st one again and you cannot scroll to the left anymore? Although you just came from that place?
If you don't want any infinite scrolling just use a default scrollView!
I have using following Code to display 5 UIButtons in Scrollview it works for as you want.you can use it for 5 pictures Check it.
- (void)viewDidLoad
{
UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 407, 320, 80)];
[self.view addSubview:scrollview];
int i;
int spacex = 5;
int spacey=5;
for ( i = 0; i <5; i++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn = [[UIButton alloc] initWithFrame:CGRectMake(spacex, spacey, 115, 45)];
btn.backgroundColor = [UIColor greenColor];
[btn setTitleColor: [UIColor blackColor] forState: UIControlStateNormal];
spacex = spacex + 120;
[scrollview addSubview:btn];
}
scrollview.contentSize = CGSizeMake(scrollview.frame.size.height*(i+2) , scrollview.frame.size.height);
[super viewDidLoad];
}
You can changed it according to your requirments.hope it works for you.Thanks.
I am developing a Universal app, and there is a UIButton in it which works fine with iPhone but when I click it in iPad it requires many click attempts to get the touch event occur.
e.g. after 5-6 clicks it executes click event.
Below is UIButton code. Please help.
UIView *footer = [[[UIView alloc] initWithFrame:(CGRectMake(0, 0, self.tableView.frame.size.width, 54))] autorelease];
float buttonWidth = (int)((self.tableView.frame.size.width - 12 - 12) / 3);
float buttonHeight = 44;
if (clientState.Devicetype == 1) // 1=Ipad
buttonHeight = 90;
cash = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
cash.frame = CGRectMake(6, 10, buttonWidth, buttonHeight);
[cash setTitle:#"Cash" forState:UIControlStateNormal];
[cash setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
[cash addTarget:self action:#selector(handleCash:) forControlEvents:UIControlEventTouchUpInside];
cash.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
if (clientState.Devicetype == 1) // 1=Ipad
{
cash.titleLabel.font = [UIFont systemFontOfSize:28];
}
[footer addSubview:cash];
self.tableView.tableFooterView = footer;
You should check to make sure that your buttons are the correct size:
[cash sizeToFit]
I've experienced that if some other view is blocking it (and you click on that part of your button it won't fire off the event) it will take several clicks because you eventually press the button where it's not being covered. So make sure no other frame/bounds is over the top of your button and make sure your button is sized correctly.
I agree with #Inturbidus that it's probably another transparent view covering part of the button. I find the best way to troubleshoot this is to change the background color on all my other views (scrollviews, etc) to make sure they are behaving like I think they are. Sometimes it will surprise you when you see where they are actually positioned with background color turned on.
I have two little problems with my UIScrollView.
I managed to create scroll view, which is similar to the picker view except that it's horizontal.
The problem n.1 is - How do I get the number which the user tapped?
The problem n.2 is - How do I make the scrollview to go round and round - never-ending?
A question - Is it possible to make some "selection indicator"?
Here is my code:
numberArray = [NSArray arrayWithObjects:#"1", #"2", #"3", #"4", #"5",
#"6", #"7", #"8", #"9", #"10", #"11", #"12", #"13", #"14", #"15",
#"16", #"17", #"18", #"19", #"20", #"21", #"22", #"23", #"24", #"25",
#"26", #"27", #"28", #"29", #"30", #"31", #"32", #"33", #"34", #"35",
#"36", #"37", #"38", #"39", #"40", #"41", #"42", #"43", #"44", #"45",
#"46", #"47", #"48", #"49", #"50", #"51", #"52", #"53", #"54", #"55",
#"56", #"57", #"58", #"59", #"60", #"61", #"62", #"63", #"64", #"65",
#"66", #"67", #"68", #"69", #"70", #"71", #"72", #"73", #"74", #"75",
#"76", #"77", #"78", #"79", #"80", #"81", #"82", #"83", #"84", #"85",
#"86", #"87", #"88", #"89", #"90", #"91", #"92", #"93", #"94", #"95",
#"96", #"97", #"98", #"99", #"100", nil];
masterDividerView = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 44)];
morePeople = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 53)];
morePeople.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
morePeople.delegate = self;
[morePeople setBackgroundColor:[UIColor whiteColor]];
[morePeople setCanCancelContentTouches:NO];
morePeople.showsHorizontalScrollIndicator = NO;
morePeople.showsVerticalScrollIndicator = NO;
morePeople.clipsToBounds = NO;
morePeople.scrollEnabled = YES;
morePeople.pagingEnabled = NO;
NSUInteger nimages = 0;
NSInteger tot=0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *label = [numberArray objectAtIndex:nimages];
if (tot==99) {
break;
}
if (99==nimages) {
nimages=0;
}
UILabel *labelView = [[UILabel alloc] init];
labelView.text = label;
labelView.lineBreakMode = UILineBreakModeWordWrap;
labelView.numberOfLines = 0;
[labelView sizeToFit];
labelView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
CGRect rect = labelView.frame;
rect.size.height = 53;
rect.size.width = 40;
rect.origin.x = cx;
rect.origin.y = 0;
labelView.frame = rect;
[morePeople addSubview:labelView];
cx += labelView.frame.size.width+5;
tot++;
}
self.pageControl.numberOfPages = nimages;
[morePeople setContentSize:CGSizeMake(cx, [morePeople bounds].size.height)];
[masterDividerView addSubview:morePeople];
[self.view addSubview:masterDividerView];
If anybody knows a good solution to this, I would be very happy!!!! :))
Your question is too wide to make a detailed answer, but yes, everything of what you're talking about can be solved in a quite easy way.
The problem n.1 is - How do I get the number which the user tapped?
If you mean to know what element is chosen by your UIScrollView at the moment, then it's not a problem: UIScrollView always knows its position (contentOffset), which gives you the easy possibility to define, which object is chosen (which object you're working with) now.
If you mean to know when the user tapped by his finger one of the elements of your "picker view" (UIScrollView), then I would say that the answer to this depends on how you actually represent your data (like if you see one or several elements of your scrollView at a time on your screen). But in any case you can easily solve this by using UITapGestureRecognizer. Smth like:
// add gesture recognizers to the scroll view
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[singleTap setNumberOfTapsRequired:1];
[self.yourScrollView addGestureRecognizer:singleTap];
[singleTap release];
And then to scroll it programmatically in your selector you do smth like:
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint pointOfTouch = [gestureRecognizer locationInView:self.view];
if ( (pointOfTouch.x > self.rightArrowMin) && (pointOfTouch.x < self.rightArrowMax) ) {
[scrollView setContentOffset:CGPointMake(lastOffset + self.lengthOfLabel, 0) animated:YES];
} else if ( (pointOfTouch.x > self.leftArrowMin) && (pointOfTouch.x < self.leftArrowMax) ) {
[scrollView setContentOffset:CGPointMake(lastOffset - self.lengthOfLabel, 0) animated:YES];
}
}
The problem n.2 is - How do I make the scrollview to go round and round - never-ending?
It can be solved if you know the algorithm of calculating the next/previous or random element in the sequence of elements of your scrollView.
Basically, I solved this same thing for myself in one of my projects (free app "IJCAI11" in the appStore, there you can see at the work of a datePicker in the details of any chosen conference's day: there is applied the algorithm of infinite scrolling view, the limits I applied later only from design point of view).
The scheme I use there is simple, though perhaps a bit weird (before reading ahead, note that in my case I see only one element of scrollView on the screen, when the scrollView is in nonscrolling state):
I create the UIScrollView with 3 (in case you see more than 1 element at a time this can be like 5, 7, ..., 2N+1 according to your very case) labels;
Make the second (central) label active.
Assign proper value to all 3 (2N+1) labels. On this step your second (central) label will contain data of (will show) the default value.
When user scrolls one step left/right (to the position M_pos), you do it in a standard way, since your neighboring to central labels contain correct data (M).
Then you take this new active value (M) and apply it for your central label (this is gonna be behind the scene, therefore the user wont see this on the screen), then you recalculate ALL the other labels properly ( ..., M-1, M, M+1, ...), including your M_pos position(!).
With "animated:NO" mode you shift your scrollView to your central position. In this case user doesn't see anything, when in fact his scrollView was moved from position M_pos to the central position. All neighboring labels are already recalculated and you are ready to repeat the point 4 any number of times you wish, making a strong feeling for user, that he works with the scrollView with a huge number of elements (whereas in practice your just work with 3 (2N+1) labels, changing their content after every movement).
A question - Is it possible to make some "selection indicator"?
If I understand this question correctly, then just consider the View/Subview thing and in particular the function addSubview of View class ;)
Hope this helps!
I'm not sure if I understood your question right, but did you already think of using a NSTimer to repeat events with a certain speed or during a certain period of time? (Pointing at your "round and round thing".)
I have created buttons are programmatically and set the button tags.
View Did Load:
I have created one view and added the buttons are sub view into that view.
-(void) viewDidLoad
{
self.answerSubview = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 320, 230)];
self.answerSubview.backgroundColor = [UIColor clearColor];
[self.view addSubview:answerSubview];
[self buttonCreation];
}
-(void) buttonCreation{
int x =100;
for(i = 0; i < 4; i++) {
UIButton *answerBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[answerBtn setFrame:CGRectMake(40, x, 260, 40)];
answerBtn.tag = ar[i];
[answerBtn setTitle:[answerList objectAtIndex:i] forState:UIControlStateNormal];
[self.answerSubview addSubview:answerBtn];
x = x+50;
}
}
And i want to set the background image for the certain index of the button, when the time is finished,
-(void) timerFinished
{
for (UIView* view in [self.answerSubview subviews]) {
if([view isKindOfClass:[UIButton class]]){
UIButton *btn = (UIButton*)view;
NSLog(#"button value %d", btn.tag);
if(btn.tag == correctIndex)
{
[btn setBackgroundImage:[UIImage imageNamed:#"selected_correct_answer.png"] forState:UIControlStateNormal];
}
}
}
}
But every time,the tag values are added into the stack,I have randomly generated numbers and set it into the button tags, so now it comes like,
REsult:
First time, Second time,
0 0
1 1
3 3
2 2
3
1
2
0
(Actually my expected result is 3 1 2 0).
So how could i remove the previous tag values and get the correct tag values at a time.
Please help me out.
There are two things you can consider doing. Since the only thing that changes on every iteration is the text on the button. You could probably reuse them. Setup once and put them in ivars. On every iteration, change the text and tag of the button.
If that is not the route you're interested in, you can probably send removeFromSuperview message to those four button objects.
However, the first method is a better approach in my opinion because it will do away with continuous creation-destruction cycle.