I am adding UIScrollView from Interface builder to my xib file. The scrollview is a child of ViewController's view and it also has some other siblings which are on ViewController's view.
Now i am setting the contentSize of the scrollview in viewDidLoad method and also tried to set this in viewDidLayoutSubviews method but the scrollview doesn't scroll. I am sure that the content area of my scrollview is bigger than the frame of the scollview.
Every thing works fine when i add scrollview in my code using the following line
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20.0, 58.0, 282.0, 200.0)]
but it didn't scroll at all when use the IBOutlet in my code here is my code for viewDidLoad with scollView from Interface builder.
- (void)viewDidLoad
{
[super viewDidLoad];
ALog();
NSUInteger i = 0;
float margin = 0.0;
UIImage *previewImg = nil;
for (i = 0; i < [[_settingsDict objectForKey:#"fullscreenWidgetIDsArray"] count]; i++) {
previewImg = [UIImage imageNamed:[NSString stringWithFormat:#"image_%#", _dict[#"images"][i]]];
if (previewImg == nil) {
[UIImage imageNamed:#"image_2.png"];
}
UIImage *backgroundImg = [UIImage imageNamed:#"image_border.png"];
UIImage *backgroundHighlightedImg = [UIImage imageNamed:#"image_selected.png"];
BOOL selected = [_dict[#"images"][i] unsignedIntegerValue] == [_dict[#"ID"] unsignedIntegerValue];
UIImageView *gridElementView = [[UIImageView alloc] initWithImage:backgroundImg];
[gridElementView setHighlightedImage:backgroundHighlightedImg];
[gridElementView setHighlighted:selected];
gridElementView.userInteractionEnabled = YES;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(6, 5, previewImg.size.width, previewImg.size.height);
[button setImage:previewImg forState:UIControlStateNormal];
button.contentMode = UIViewContentModeCenter;
margin = (_scrollView.frame.size.width - kElements_per_row * (gridElementView.frame.size.width + 2*kPreview_border_size))/3;
gridElementView.frame = CGRectMake(margin + i%2*(margin + gridElementView.frame.size.width + 2*kPreview_border_size), margin + i/2*(margin + gridElementView.frame.size.height + 2*kPreview_border_size), gridElementView.frame.size.width + 2*kPreview_border_size, gridElementView.frame.size.height + 2*kPreview_border_size);
button.tag = gridElementView.tag = [_settingsDict[#"fullscreenWidgetIDsArray"][i] unsignedIntegerValue];
[button addTarget:self action:#selector(previewBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
[_thumbnailsViewsArray addObject:gridElementView];
[gridElementView addSubview:button];
[_scrollView addSubview:gridElementView];
}
_scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width, margin + (i/2)*(margin + previewImg.size.height + 2*kPreview_border_size));
NSLog(#"contentsize : %#",NSStringFromCGSize(_scrollView.contentSize));
}
In this code i am adding UIButtons inside scrollview in two columns. There are total 6 UIButtons that needs to be added in scrollview. These button were added but scrollview will not scroll at all. Making the scrollEnabled property to yes also didn't work.
Any help will be great.
Thanks
Related
I am creating a customview which is a subclass of UIScrollView. I am adding UIButtons inside UIScrollView dynamically along with images and actions. But scrollview is not scrolling horizontally with buttons. I know this topic is discussed many times on SO. I tried all posts posted on SO, but not getting expected result. Any suggestion about where i am going wrong will be helpful.
MyCustomView.h
#interface MyCustomView : UIScrollView
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
+ (id)customView;
#end
MyCustomView.m
#implementation MyCustomView
#synthesize scrollView;
+ (id)customView
{
MyCustomView *customView = [[[NSBundle mainBundle] loadNibNamed:#"MyCustomView" owner:nil options:nil] lastObject];
if ([customView isKindOfClass:[MyCustomView class]])
return customView;
else
return nil;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[self setupHorizontalScrollView];
}
- (void)setupHorizontalScrollView
{
//scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blueColor]];
[scrollView setCanCancelContentTouches:YES];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = NO;
scrollView.scrollEnabled = YES;
//scrollView.pagingEnabled = YES;
CGFloat cx = 0;
NSArray *buttons = #[#{#"Tag":#1,#"Image":[UIImage imageNamed:#"borderImage1.png"]},
#{#"Tag":#2,#"Image":[UIImage imageNamed:#"borderImage2.png"]},
#{#"Tag":#3,#"Image":[UIImage imageNamed:#"borderImage3.png"]},
#{#"Tag":#4,#"Image":[UIImage imageNamed:#"borderImage4.png"]},
#{#"Tag":#1,#"Image":[UIImage imageNamed:#"borderImage1.png"]},
#{#"Tag":#2,#"Image":[UIImage imageNamed:#"borderImage2.png"]},
#{#"Tag":#3,#"Image":[UIImage imageNamed:#"borderImage3.png"]},
#{#"Tag":#4,#"Image":[UIImage imageNamed:#"borderImage4.png"]},
#{#"Tag":#1,#"Image":[UIImage imageNamed:#"borderImage1.png"]}
];
// CGRect frame = CGRectMake(0.0f, 0.0f, 50.0f, 30.0f);
for (NSDictionary *dict in buttons)
{
UIButton *button =[UIButton buttonWithType:UIButtonTypeRoundedRect];
CGRect rect = button.frame;
rect.size.height = 40;
rect.size.width = 40;
rect.origin.x = cx;
rect.origin.y = 0;
button.frame = rect;
button.tag = [dict[#"Tag"] integerValue];
[button setImage:dict[#"Image"]
forState:UIControlStateNormal];
// [button addTarget:self action:#selector(buttonAction:)
// forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:button];
//frame.origin.x+=frame.size.width+20.0f;
cx += button.frame.size.width+5;
}
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
#end
I went through below SO links, but didn't get solution.
LINK1 LINK2LINK3 LINK4
To be able to scroll you need to keep a view over scrollview that goes out of the bound of the screen. So drag a view and enlarge it beyong the device bounds so that it would be able to hold your subviews.
Its better to use UICollectionView for this kind of a problem. It is easier to implement and also will help you do all necessary manipulations.
Your MyCustomView is a subClass of UIScrollView. So you don't need to add UIScrollView property to your class. Delete scrollView property and replace all self.scrollView with self
So I'm having issues with the buttons for the filters in my photo app. I'm not exactly sure why, but they've suddenly stopped working. The selector is not being called when they're tapped, but I have no idea why. They were working just fine a few days ago, but for some reason they're not now. I've checked the UIView subviews array, verified that it's right on top. I need a way to see if, for some reason, the touches are not making it to the button. I'm not sure how to do this.
I wish I had more information to give, but this is all I've got. I hope someone has some suggestions because I'm at wit's end with it.
Thanks in advance!
Button Creation Method:
-(void)createFilterButtonsForThumbnail:(UIImage *)thumbnail
{
UIView *filtersContainer = self.filterContainer;
CGRect buttonFrame = CGRectMake(kFilterFrameThickness, kFilterFrameThickness,
thumbnail.size.width, thumbnail.size.height);
CGFloat frameWidth = thumbnail.size.width+(2*kFilterFrameThickness);
CGFloat frameHeight = kFilterPickerHeight;
UIEdgeInsets backgroundInsets = UIEdgeInsetsMake(0, kFilterFrameThickness, 0, kFilterFrameThickness);
UIImage *buttonBackgroundImage = [[UIImage imageNamed:#"FilmReel"] resizableImageWithCapInsets:backgroundInsets];
for (int i = 0;i<(self.filterPaths.count+kFilterNonLookups+1);i++){
UIImageView *buttonBackground = [[UIImageView alloc] initWithFrame:CGRectMake(kFilterSidePadding+(i*(frameWidth+kFilterSidePadding)),
0,
frameWidth,
frameHeight)];
[buttonBackground setImage:buttonBackgroundImage];
UIButton *thumbnailButton = [[UIButton alloc] initWithFrame:buttonFrame];
UIImage *filteredThumbnail = [self applyFilterAtIndex:i ToImage:thumbnail];
[thumbnailButton setImage:filteredThumbnail forState:UIControlStateNormal];
[thumbnailButton addTarget:self action:#selector(filterSelected:) forControlEvents:UIControlEventTouchUpInside];
[thumbnailButton setTag:i];
[buttonBackground addSubview:thumbnailButton];
[filtersContainer addSubview:buttonBackground];
if ((i > (kFilterProMinimumIndex)) && ([self isProVersion]) == NO){
UIImageView *proTag = [[UIImageView alloc] initWithImage:nil];
CGRect proFrame = CGRectMake(buttonFrame.origin.x,
buttonFrame.origin.y + buttonFrame.size.height - kFilterProIconHeight-kFilterFrameThickness,
kFilterProIconWidth,
kFilterProIconHeight);
[proTag setBackgroundColor:[UIColor orangeColor]];
[proTag setFrame:proFrame];
[thumbnailButton addSubview:proTag];
[self.filterProTags addObject:proTag];
}
}
}
Selector Method:
-(void)filterSelected:(UIButton *)button
{
NSLog(#"Pressed button for index %i",button.tag);
int buttonTag = button.tag;
if ((buttonTag < kFilterProMinimumIndex+1) || ([self isProVersion] == YES)){
[self.imageView setImage:[self applyFilterAtIndex:buttonTag ToImage:self.workingImage]];
}
else {
[self processProPurchaseAfterAlert];
}
}
I see a couple issues in this, but I'm not sure which ones are causing it to break. First, you should instantiate your button using buttonWithType: on UIButton:
UIButton *thumbnailButton = [UIButton buttonWithType:UIButtonTypeCustom];
[thumbnailButton setFrame:buttonFrame]
The reason for this is UIButton is a class cluster, and you should let the OS give you the correct button.
Secondly, you're adding the Button as a Subview of an UIImageView, which by default, has userInteractionEnabled set to NO.
This property is inherited from the UIView parent class. This class
changes the default value of this property to NO.
You should have the button be one large button, with the background of the button be the image you want it to be.
I have been following a tutorial for paging through images within a UIScrollview.
The paging with UIScrollview section.
I now want to change this so instead of an UIimageview, it displays a UITextview. With different text as it is paged.
Not sure as to how to implement the textview instead of the imageview.
any ideas?
Thanks
code being used:
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
// 1
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
// 2
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
//UITextView *theTextView;
theTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
theTextView.scrollEnabled = NO;
theTextView.editable = NO;
theTextView.text = [NSString stringWithFormat:#"This is a very long text"];
// 3
//UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
theTextView.contentMode = UIViewContentModeScaleAspectFit;
theTextView.frame = frame;
[self.scrollView addSubview:theTextView];
// 4
[self.pageViews replaceObjectAtIndex:page withObject:theTextView];
}
}
They are both UIView subclasses. It should work the exact same way. Simply deactivate allowUserInteraction on the UITextViews if you don't want them to scroll and the UIScrollView should scroll the exact same way as if it was filled with UIImageViews.
You'd add the UITextView the exact same way you'd add a UIImageView. Initialize a UITextView, set up any properties you want on it, and add it to the UIScrollView as a subview. So where ever you're adding UIImageViews, replace that code with something like this:
self.theTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
self.theTextView.scrollEnabled = NO;
self.theTextView.editable = NO;
... //however else you want to modify your UITextView
[self.theScrollView addSubview:self.theTextView];
I have a UIScrollView with many other subviews inside it. Most of the subviews are UITextView's and when they are all loaded, the scrolling and everything is fine. But for one of the views, I am loading a UIView with a MKMapView and a UITextView inside of it. When the user wants to scroll the UIScrollView, they cannot touch the UIView or its contents. I cannot set setUserInteractionEnabled to NO because I need the user to be able to click on the MKMapView and then go to another UIViewController for the map. Are there any suggestions regarding this? I have my code for the above below:
CGRect dealDescRect = CGRectMake(10, 10, delegate.scrollView.frame.size.width - 22 - 20, 120);
mapView = [[MKMapView alloc] initWithFrame:dealDescRect];
mapView.layer.cornerRadius = cornerRadius;
mapView.scrollEnabled = NO;
mapView.zoomEnabled = NO;
BOOL result = [self loadAddressIntoMap];
if (result == TRUE) {
UITapGestureRecognizer* recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[mapView addGestureRecognizer:recognizer];
}
UITextView *addressTextView = [self generateTextView:addressText :5];
addressTextView.editable = NO;
[addressTextView setFont:[UIFont systemFontOfSize:fontSize]];
[addressTextView setUserInteractionEnabled:NO];
CGRect addressTextViewFrame = addressTextView.frame;
addressTextViewFrame.origin.x = 0;
addressTextViewFrame.origin.y = 130;
addressTextViewFrame.size.height = addressTextView.contentSize.height + 15;
addressTextView.frame = addressTextViewFrame;
CGRect viewRect = CGRectMake(10, 145, delegate.scrollView.frame.size.width - 22, addressTextView.contentSize.height + 135);
viewRect.origin.x = 11;
viewRect.origin.y = startTop;
UIView *view = [[UIView alloc] initWithFrame:viewRect];
view.layer.cornerRadius = cornerRadius;
[view setBackgroundColor:[UIColor whiteColor]];
[view addSubview:mapView];
[view addSubview:addressTextView];
EDIT
For some weird reason, if I change the UIView to a UITextView, it works! Not sure what the real solution here is though. I just disable editing.
If it were me, instead of using gesture recognizers to watch for a tap on the map I'd create a UIButton of a custom type (UIButtonTypeCustom) and give it no background and no text, and place it on top of the map with the same frame as the map.
This has the benefit of preventing the user from interacting with the map, moving to the next page as you want and if the user starts scrolling even when over the map they are able to.
i have a modal view that is called from a table view. Whenever i call the modal view, i set a small view, inside the modal view, with some scrollable pictures inside it. The problem is that when i go back to the table view and select another row of the table, the old images are supposed to disappear and the new ones appear instead, but that is not happening. Seems like when i first load the modal view, it fills with the initial 2 pics and when i load it again it keeps adding the new pictures with the old ones..
Here is the code:
- (void)layoutScrollImages {
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
//NSMutableArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake(([self.nomeFotos count] * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
and:
- (void)setScrollingImages {
//self.view.backgroundColor = [UIColor viewFlipsideBackgroundCol];
// 1. setup the scrollview for multiple images and add it to the view controller
//
// note: the following can be done in Interface Builder, but we show this in code for clarity
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView1.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
for (i = 1; i <= [self.nomeFotos count]; i++)
{
NSString *imageName = [NSString stringWithFormat:[self.nomeFotos objectAtIndex:(i-1)]];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
NSLog(#"%#", imageName);
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView1 addSubview:imageView];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
}
i just figured what i wanted, a solution is to remove all the current subviews and then add the new views.. the code is as follow:
for (UIView* subView in [self.view.subviews]) {
[subView removeFromSuperview];
}
I put this code in my view will appear and everytime the view appears, it clears its subviews and the i call the method to add the new subviews (pictures).
Thanks