UIViews in scrollviews - ios

I have a UIScrollview with UIView, and in every UIView has a labels and image. I'm looping this view and it's working fine, but I have a button Grid and when i press this they changed into grid view. The problem is the last item is not working fine as the others. One of the labels are hidden in the last item. And when I pressed the list view button, the last item has a problem again, the labels are complete but the 'View' didn't changed.
-update.
the content size is okay, and it's leaving a space for the last item but the last item is somewhere. I can't post images yet because of the reputation.
`-(void)actionList {
int prods = 0;
isGrid = NO;
for(UIView*iView in sv_results.subviews){
for(UILabel *iView2 in iView.subviews){
if([iView2 isMemberOfClass:[UILabel class]]){
if(iView2.tag == 0)
{
iView2.frame = CGRectMake(80, 0, 150, 50);
iView2.font = [UIFont boldSystemFontOfSize:12.0f];
NSLog(#"%#",iView2.text);
}
else if(iView2.tag == 1)
{
pricewidth = [iView2.text sizeWithAttributes:#{NSFontAttributeName:[UIFont systemFontOfSize:13.0f]}];
iView2.frame = CGRectMake(80, 20, pricewidth.width+1, 50);
iView2.font = [UIFont systemFontOfSize:13.0f];
for(UIView *discountline in iView2.subviews)
{
discountline.frame = CGRectMake(0, iView2.frame.size.height/2, iView2.frame.size.width, 1);
}
}
else if(iView2.tag == 2)
{
iView2.frame = CGRectMake(screenRect.size.width-60, 30, 50, 15);
iView2.font = [UIFont systemFontOfSize:10.0f];
}
else if(iView2.tag == 3)
{
iView2.frame = CGRectMake(140, 20, 150, 50);
iView2.font = [UIFont systemFontOfSize:13.0f];
}
}
if([iView2 isMemberOfClass:[AsyncImageView class]]){
iView2.frame = CGRectMake(15,12,50,50);
iView2.layer.cornerRadius = 5;
}
}
NSLog(#"all avail data > %i",allAvailableData);
for(int i = 0;i<allAvailableData;i++)
{
if(iView.tag == i)
{
NSLog(#"UIView tag > %i",iView.tag);
iView.frame = CGRectMake(0,((i-1)*75),320,75);
}
}
prods++;
iView.layer.borderWidth = .3f;
}
NSLog(#"%i",prods);
sv_results.contentSize = CGSizeMake(320,(allAvailableData)*75);
}`

Related

ScrollView doesn't work on iPad but works on iPhone

I have a scrollview and it is full off buttons. this scrollview work iphone but not work on ipad
#define scrollViewSizeForiPad 1000
#define scrollViewSizeForiPhone 600
#define locationButtonSizeForiPhone 50
#define locationButtonSizeForiPad 30
i added buttons like this
lc_button.frame = CGRectMake(0, 0, buttonSize, buttonSize);
[_uiScrollForLocations addSubview:lc_button];
and some labels
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
buttonSize = buttonWidthHeightForiPad;
lc_label.font = [UIFont systemFontOfSize:14];
lc_label.frame = CGRectMake(3, 100, buttonSize, 20);
} else {
buttonSize = buttonWidthHeightForiPhone;
lc_label.font = [UIFont systemFontOfSize:9];
lc_label.frame = CGRectMake(8, 50, buttonSize, 10);
}
[_uiScrollForLocations addSubview:lc_label];
-(void) showLocations:(NSMutableArray *)lc_array {
[self hideAllLocations];
[self addButtonToView:lc_array whichView:_uiScrollForLocations type:#"Location"];
CGSize pagesScrollViewSize = _uiScrollForLocations.frame.size;
int viewHeight;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
viewHeight = buttonWidthHeightForiPad;
} else {
viewHeight = buttonWidthHeightForiPhone;
}
_uiScrollForLocations.contentSize = CGSizeMake(pagesScrollViewSize.width, viewHeight);}
It happen because contentSize <= _uiScrollForLocations.frame
Need set
_uiScrollForLocations.alwaysBounceVertical = YES
or
_uiScrollForLocations.alwaysBounceHorizontal = YES

How to Create Button in in multiple row and column in iOS?

I am stuck in this position from last 3 days. I am unable to find out how to solve this. I have multiple data in a array. According to data I have to create a route in my Application. I am creating the button in a for loop. but its coming one row by row. But my requirement is like, in every row it should be a opposite direction.
This is my requirement.
This purple color is my buttons, and red colors are path.
int x_pos = 40;
int y_pos = 50;
for (int i = 0; i < 5 ; i ++)
{
UIButton *courseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
courseBtn.frame = CGRectMake(x_pos, y_pos, 40, 40);
courseBtn.backgroundColor = [UIColor purpleColor];
[self.courseMapScroll addSubview:courseBtn];
courseBtn.layer.cornerRadius = courseBtn.frame.size.height/2;
courseBtn.layer.masksToBounds = YES;
NSLog(#"x_pos == %d",x_pos);
x_pos = x_pos + (SCREEN_WIDTH - 120);
if (x_pos > 320)
{
x_pos = 40;
y_pos = y_pos + 100;
}
[self.courseMapScroll setContentSize:CGSizeMake(SCREEN_WIDTH, y_pos + 70)];
}
My code is like this
Please anybody can help me. Please
Thanks alots
Here it is, exactly how you asked for it (with the green line that you requested in chat). Have fun tweaking the values :)
int numButtons = 6;
int yInterval = 100;
int leftX = 50;
int rightX = self.view.frame.size.width - leftX*2;
int lineWidth = 6;
int buttonRadius = 40;
int topMargin = 60;
for (float i = 1; i < numButtons+1 ; i++) {
float yPos = (ceil(i/2)-1)*yInterval+topMargin;
BOOL isRightDirection = (fmod(ceil(i/2),2) == 1);
BOOL isEven = (fmod(i,2) == 0);
BOOL isOnLeft = (isRightDirection != isEven);
float xPos = (isOnLeft) ? leftX : rightX;
if (i != numButtons) {
double nextUnlockedDecimal = (double)nextPercentUnlocked/100;
UIView *redLine = [[UIView alloc] initWithFrame:CGRectZero];
redLine.backgroundColor = [UIColor redColor];
UIView *greenLine = [[UIView alloc] initWithFrame:CGRectZero];
greenLine.backgroundColor = [UIColor greenColor];
if (isEven) {
//Vertical
int xToUse = (isRightDirection) ? rightX : leftX;
redLine.frame = CGRectMake(xToUse + buttonRadius/2 - lineWidth/2, yPos + buttonRadius/2, lineWidth, yInterval);
if (i == latestUnlocked) {
greenLine.frame = CGRectMake(xToUse + buttonRadius/2 - lineWidth/2, yPos + buttonRadius/2, lineWidth, nextUnlockedDecimal * yInterval);
} else if (i < latestUnlocked) {
greenLine.frame = redLine.frame;
}
} else {
//Horizontal
redLine.frame = CGRectMake(leftX + buttonRadius/2, yPos + buttonRadius/2 - lineWidth/2, rightX-leftX, lineWidth);
if (i == latestUnlocked) {
double greenLineX = (isRightDirection) ? leftX + buttonRadius/2 : rightX + buttonRadius/2 - nextUnlockedDecimal * (rightX-leftX);
greenLine.frame = CGRectMake(greenLineX, yPos + buttonRadius/2 - lineWidth/2, nextUnlockedDecimal * (rightX-leftX), lineWidth);
} else if (i < latestUnlocked) {
greenLine.frame = redLine.frame;
}
}
greenLine.layer.cornerRadius = 2.5;
[self.view addSubview:redLine];
[self.view addSubview:greenLine];
}
UIButton *courseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
courseBtn.backgroundColor = [UIColor purpleColor];
courseBtn.layer.cornerRadius = buttonRadius/2;
courseBtn.layer.masksToBounds = YES;
courseBtn.frame = CGRectMake(xPos, yPos, 40, 40);
NSString *numStr = [NSString stringWithFormat:#"%i",(int)i];
[courseBtn setTitle:numStr forState:UIControlStateNormal];
[self.courseMapScroll setContentSize:CGSizeMake(SCREEN_WIDTH, yPos + 70)];
[self.courseMapScroll addSubview:courseBtn];
}
I don't know why I really did that... This should work, I haven't tested it though... I would recommend you to use a global mutable array (courseButtons) to store the buttons so you can check on the target their index against the array and know which one was clicked.
CGFloat buttonHorizontalMargin=40;
CGFloat buttonVerticalMargin=50;
CGFloat buttonSize=40;
CGFloat x_pos = buttonHorizontalMargin;
CGFloat y_pos = buttonVerticalMargin;
[self.courseMapScroll setContentSize:CGSizeMake(self.courseMapScroll.bounds.size.width, y_pos + buttonSize+buttonVerticalMargin*0.5)];
for (NSInteger i = 0; i < [_buttonPoints count] ; i ++)
{
UIButton *courseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[courseBtn setTitle:[NSString stringWithFormat:#"%ld",(long)i] forState:UIControlStateNormal];
[courseBtn setTranslatesAutoresizingMaskIntoConstraints:YES];
[courseBtn setAutoresizesSubviews:(((i+1)%2==0&&(i+1)%4!=0)||(i+1)%3==0)?UIViewAutoresizingFlexibleLeftMargin:UIViewAutoresizingRightMargin];
[courseBtn addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
courseBtn.frame = CGRectMake(x_pos, y_pos, buttonSize, buttonSize);
courseBtn.backgroundColor = [UIColor purpleColor];
[self.courseButtons addObject:courseBtn];
[self.courseMapScroll addSubview:courseBtn];
courseBtn.layer.cornerRadius = courseBtn.frame.size.height*0.5;
courseBtn.layer.masksToBounds = YES;
NSLog(#"x_pos == %d",x_pos);
if((i+1)%4){
x_pos = buttonHorizontalMargin;
}else if((i+1)%3||(i+1)%2){
x_pos = self.courseMapScroll.bounds.size.width-buttonHorizontalMargin-buttonSize;
}else{
x_pos = buttonHorizontalMargin;
}
if (i>0 && i%2==0){
y_pos = y_pos + buttonSize+buttonVerticalMargin;
[self.courseMapScroll setContentSize:CGSizeMake(self.courseMapScroll.bounds.size.width, y_pos + buttonSize+buttonVerticalMargin*0.5)];
}
}

UIScrollView with many subviews takes time to process

I have an UIScrollView with subviews. It contains a result list of products/items. UIViewwith UIImageView and UILabel. It may contain many items. My problem is when I'm pressing the button(Grid Button) to change the UI result into grid view, it takes time before it finishes the processing. Is there a way to make this faster? Like remove images which are not visible in screen/UIScrollView?
Here's my code for listView
-(void)actionList {
NSLog(#"List!!");
isGrid = NO;
for(UIView*iView in sv_results.subviews){
for(UILabel *iView2 in iView.subviews){
if([iView2 isMemberOfClass:[UILabel class]]){
if(iView2.tag == 0)
{
iView2.frame = CGRectMake(80, 0, 150, 50);
iView2.font = [UIFont boldSystemFontOfSize:12.0f];
}
else if(iView2.tag == 1)
{
pricewidth = [iView2.text sizeWithAttributes:#{NSFontAttributeName:[UIFont systemFontOfSize:13.0f]}];
iView2.frame = CGRectMake(80, 20, pricewidth.width+1, 50);
iView2.font = [UIFont systemFontOfSize:13.0f];
for(UIView *discountline in iView2.subviews)
{
discountline.frame = CGRectMake(0, iView2.frame.size.height/2, iView2.frame.size.width, 1);
}
}
else if(iView2.tag == 2)
{
iView2.frame = CGRectMake(screenRect.size.width-60, 30, 50, 15);
iView2.font = [UIFont systemFontOfSize:10.0f];
}
else if(iView2.tag == 3)
{
iView2.frame = CGRectMake(140, 20, 150, 50);
iView2.font = [UIFont systemFontOfSize:13.0f];
}
else {
iView2.frame = CGRectMake(80, 0, 150, 50);
iView2.font = [UIFont boldSystemFontOfSize:12.0f];
}
}
if([iView2 isMemberOfClass:[AsyncImageView class]]){
iView2.frame = CGRectMake(15,12,50,50);
iView2.layer.cornerRadius = 5;
}
}
for(int i = 0;i<=allAvailableData;i++)
{
if(iView.tag == i)
{
iView.frame = CGRectMake(0,((i-1)*75),320,75);
}
//sv_results.contentSize = CGSizeMake(320,yPosition);//optional resize height scrollview from gridview
}
iView.layer.borderWidth = .3f;
}
sv_results.contentSize = CGSizeMake(320,(allAvailableData)*75);
}
It can take a time because of images. If you are loading a lots of images in main thread then it is normal to take a time. Try to use lazy image loading with UITableView. I use this in my project and easy to implement and use. http://www.theappguruz.com/sample-code/ios-lazy-loading-images/ there is some codes and helps. I did not check this but it looks also fine https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
Just use
scrollView.delaysContentTouches = NO;
A Boolean value that determines whether the scroll view delays the handling of touch-down gestures.
If the value of this property is YES, the scroll view delays handling the touch-down gesture until it can determine if scrolling is the intent. If the value is NO , the scroll view immediately calls touchesShouldBegin:withEvent:inContentView:. The default value is YES.
This means, scrollView will delay touches by default, you can disable that functionality by above code,
Hope it will solve your problem.
I think you should implement UITableView and you can load image with "dispatch_async" so it will not take time. I hope you may get solution this way.

Certain placement of UIButtons created in for loop

I want to create UIButtons and have them separated inside a UIScrollView with pages such as:
The buttons will go from left to right then down in rows until it gets to bottom of view. It will then go to next page of the UIScrollView and continue on.
Here's my code so far:
for(NSString *num in nums) {
UIButton *test = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[test addTarget:self action:#selector(numPressed:) forControlEvents:UIControlEventTouchUpInside];
test.frame = CGRectMake(0, 0, 70, 70);
[self.view addSubview:test];
}
Some code like this:
int xOff = 10;
int yOff = 50;
int btnGap = 20;
int page = 0;
for (NSString *num in nums) {
xOff += page * _scrollView.width;
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
UIButton *test = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[test addTarget:self action:#selector(numPressed:) forControlEvents:UIControlEventTouchUpInside];
test.frame = CGRectMake(xOff+col*(70+btnGap) , yOff+row*(70+btnGap), 70, 70);
test.backgroundColor = [UIColor redColor];
[test setTitle:num forState:UIControlStateNormal];
[_scrollView addSubview:test];
}
}
page++;
}
You need to change the coordinates when invokint CGRectMake:
NSInteger i, x, y;
for(NSString *num in nums) {
...
i = i%3;
if (i==0)
{
x = 0;
y += 70;
}
x += 80;
test.frame = CGRectMake(x, y, 70, 70);
...
}
This should give you an idea on how to proceed. Also, don't forget to place the title to each button.
If you're creating and setting UIButton objects by frame then I, personally, would do it this way (surely it can be improved / optimized)
Note: This does not incorporate any page logic so you'll need to adapt it yourself.
-(void)createButtonGrid
{
int i_btnWidth = 70;
int i_btnHeight = 70;
int i_btnX = 0;
int i_btnY = -70; //offset (for first iteration in for loop) [1]
int i_btnPadding = 20;
//number of columns
int i_screenDivisions = 3;
//width of every column
int i_screenDivisionWidth = self.view.frame.size.width / i_screenDivisions;
int i_count = 40; //or, maybe, nums.count as per your logic
for (int i = 0; i < i_count; i++) {
//which column a button goes in
int i_index = (i+i_screenDivisions)%i_screenDivisions;
//increase Y position when new row begins
if (i_index == 0) { //[1]
i_btnY += i_btnHeight + i_btnPadding;
}
//calculate X position (which will be placed at the centre of every column)
i_btnX = (i_index*i_screenDivisionWidth) + (i_screenDivisionWidth/2) - (i_btnWidth/2);
//----Button creation logic----
UIButton *btnTemp = [UIButton buttonWithType:UIButtonTypeCustom];
[btnTemp setFrame:CGRectMake(i_btnX, i_btnY, i_btnWidth, i_btnHeight)];
NSString *strTitle = [NSString stringWithFormat:#"%d",i];
//or, maybe, as per your logic
//NSString *strTitle = nums[i];
[btnTemp setTitle:strTitle forState:UIControlStateNormal];
[btnTemp.titleLabel setTextColor:[UIColor yellowColor]];
//[btnTemp addTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
[btnTemp setTag:i]; //might need it later
[btnTemp setBackgroundColor:[UIColor colorWithRed:(float)(arc4random()%255)/255
green:(float)(arc4random()%255)/255
blue:(float)(arc4random()%255)/255
alpha:1.0f]];
[scrollView addSubview:btnTemp];
}
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width, i_btnY + i_btnHeight)];
}

Set button position in SBTableAlert

I was using SBTableAlert library in my app, but with iOS 7 this library won't work.
I fix it whit adding TSAlertView and dialogs are showing fine.
But my problem is that position of button is not as it should be.
I set position of the button in :
-(void)willPresentTableAlert:(SBTableAlert *)tableAlert{
int counter = 0;
for (id view_sub in self.filterAlert.view.subviews) {
if ([view_sub isKindOfClass:[UIButton class]]) {
switch (counter) {
case 0:
((UIButton*)view_sub).frame = CGRectMake(10,
10,
144,
44);
((UIButton*)view_sub).backgroundColor = [UIColor redColor];
break;
case 1:
((UIButton*)view_sub).frame = CGRectMake(169,
150,
144,
44);
break;
case 2:
((UIButton*)view_sub).frame = CGRectMake(328,
150,
144,
44);
break;
default:
break;
}
counter++;
}
}
}
The thing is that button is painted red but frame set is ignored, instead of lining in one line, they are put one under the other and out of the Alert frame.
I finally found the answer.
The problem was in TSAlertVeiw library, because it has function recalcSizeAndLayout:layout which is called at the end and overwrite your custom position of the buttons.
The solution was to add new BOOL variable in TSAlertView customLayoutOfButton and then check it before auto layout your buttons:
if (!self.customLayoutOfButton) {
CGFloat buttonHeight = [[self.buttons objectAtIndex:0] sizeThatFits: CGSizeZero].height;
if ( stacked )
{
CGFloat buttonWidth = maxWidth;
for ( UIButton* b in self.buttons )
{
b.frame = CGRectMake( kTSAlertView_LeftMargin, y, buttonWidth, buttonHeight );
y += buttonHeight + kTSAlertView_RowMargin;
}
}
else
{
CGFloat buttonWidth = (maxWidth - kTSAlertView_ColumnMargin) / 2.0;
CGFloat x = kTSAlertView_LeftMargin;
for ( UIButton* b in self.buttons )
{
b.frame = CGRectMake( x, y, buttonWidth, buttonHeight );
x += buttonWidth + kTSAlertView_ColumnMargin;
}
}
}

Resources