I'm trying to create a simple scrollView inside a tableview cell. Just like on app store, but with simpler scrolling.
The scrollview is showing up but its not scrolling at all. I've tried whole first page on google and many stackoverflow questions, can't seem to find what I'm doing wrong.
if (indexPath.row==0) {
// Clearing out cell background
[cell setBackgroundColor:[UIColor clearColor]];
[cell.contentView setBackgroundColor:[UIColor clearColor]];
// Imageviews for scrollview
UIImageView *imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,123)];
UIImageView *imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(320,0,320,123)];
imageview1.image = [UIImage imageNamed:#"flash2.png"];
imageview2.image = [UIImage imageNamed:#"IMG_2458.JPG"];
// setting up scrollview
self.scrollViewHeader = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320, 123)];
self.scrollViewHeader.scrollEnabled = YES;
self.scrollViewHeader.delegate = self;
[self.scrollViewHeader setUserInteractionEnabled:YES];
[self.scrollViewHeader setContentSize:CGSizeMake(320, 123)];
[self.scrollViewHeader addSubview:imageview1];
[self.scrollViewHeader addSubview:imageview2];
[cell.contentView addSubview:self.scrollViewHeader];
}
else{
// Normal table cells.
...
}
Thanks in advance for your answers.
In order for a scroll view to scroll, its content size must be greater than its bounds.
You have:
self.scrollViewHeader = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320, 123)];
and then
[self.scrollViewHeader setContentSize:CGSizeMake(320, 123)];
In this case, they are both the same size, therefore it won't scroll. Do:
self.scrollViewHeader = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,160, 123)];
[self.scrollViewHeader setContentSize:CGSizeMake(320, 123)];
Related
Everything works well in iOS 9.
But in iOS 8, the content is not displayed, only imageview is showed.
What i did is that I create a view and add label and UIImage to that view. Then that view is added to contentView of table Cell
create View
- (UIView *)getHeaderView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, HEADER_SECTION_HEIGHT)];
[view setBackgroundColor:[[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"Layer1Color"]]];
UILabel *taskName = [[UILabel alloc] initWithFrame:CGRectMake(5.0, SECTION_BREAK+3.0, view.frame.size.width-23.0, 20)];
[taskName setFont:[UIFont boldSystemFontOfSize:[[_themeComponent valueForKey:#"RegularFontSize"] intValue]]];
[taskName setText:combinedTask.taskDescription];
[taskName setTextColor: [[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"textPrimary"]]];
[view addSubview:taskName];
UIImageView *addressView = [[UIImageView alloc]initWithFrame:CGRectMake(5.0, SECTION_BREAK+28.0, 20, 20)];
addressView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png", #"Attr_Pin"]];
[view addSubview:addressView];
UILabel *address = [[UILabel alloc] initWithFrame:CGRectMake(35.0, SECTION_BREAK+23.0, view.frame.size.width-35.0, 30)];
[address setFont:[UIFont boldSystemFontOfSize:[[_themeComponent valueForKey:#"SmallFontSize"] intValue]]];
address.lineBreakMode = NSLineBreakByWordWrapping;
address.numberOfLines = 0;
[address setText:[NSString stringWithFormat:#"%#", unit]];
[address setTextColor: [[RNThemeManager sharedManager] colorWithHexString:[_themeComponent valueForKey:#"textPrimary"]]];
[view addSubview:address];
return view;
}
Add view to table cell
UIView *header= [self getHeaderView:tableView viewForHeaderInSection:section];
cell.taskIdLabel.hidden = YES;
[cell.contentView addSubview:header];
Anyone has any ideas? Thanks much for your help.
This is because iOS 9 Apple handle good autolayout than before.
Let add [cell layoutIfNeeded] before return cell.
Update
I have same problem before. Here is block of code that i use to solved my problem.
- (void) sizeHeaderToFit {
//call in viewLayoutSubView
UIView *myHeaderView = self.tableView.tableHeaderView;
[myHeaderView setNeedsLayout];
[myHeaderView layoutIfNeeded];
CGFloat height = [myHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
myHeaderView.frame = ({
CGRect headerFrame = myHeaderView.frame;
headerFrame.size.height = height;
headerFrame;
});
self.tableView.tableHeaderView = myHeaderView;
}
call it at viewDidLayoutSubView. Hope it helps bạn :))
I have important problem with UIScrollView.
I want to make one app like yahoo weather and using this source code : BTGlassScrollView
in this source code exist one view with name "foregroundView" that is info view. this info view appear when scrolling my ScrollView from bottom to top.
now I make and add my ScrollView by this code:
_viewScroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width + 2*blackSideBarWidth, self.view.frame.size.height)];
[_viewScroller setPagingEnabled:YES];
[_viewScroller setDelegate:self];
[_viewScroller setShowsHorizontalScrollIndicator:NO];
[self.view addSubview:_viewScroller];
_glassScrollView1 = [[BTGlassScrollView alloc] initWithFrame:self.view.frame BackgroundImage:[UIImage imageNamed:#"background3"] blurredImage:nil viewDistanceFromBottom:0 foregroundView:[self customView]];
[_viewScroller addSubview:_glassScrollView1];
in my code I write [self customView] that make me info view and this is customView function:
- (UIView *)customView {
//this method is for make UITableView
[self makeTableBuy:[[self.tableDic objectForKey:#"person"] count]];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _tableBuy.frame.size.width, _tableBuy.frame.size.height)];
view.layer.cornerRadius = 3;
view.backgroundColor = [UIColor colorWithWhite:0 alpha:.3];
[view addSubview:_tableBuy];
return view;
}
- (UITableView*)makeTableBuy:(int)numberOfRow {
_tableBuy = [[UITableView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,numberOfRow*TABLE_HEIGHT) style:UITableViewStyleGrouped];
[_tableBuy setTag:1];
[_tableBuy setBackgroundColor:[UIColor clearColor]];
_tableBuy.showsVerticalScrollIndicator = NO;
_tableBuy.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableBuy.rowHeight = TABLE_HEIGHT;
_tableBuy.scrollEnabled = NO;
_tableBuy.delegate = self;
_tableBuy.dataSource = self;
return _tableBuy;
}
now When I'm scrolling my ScrollView my info view (my tableview) moving to top and appear but my scrolling have so lagging.
please guide me how to fix this lag???
I have two views in my program. One is statusView, it's alpha is set to 0.8f. And below it is tableView. How do I disable statusView such way, that clicking on it would not click tableView. Settings userInteractionEnabled = false; didn't help.
Here is how i add views.
[self.view addSubview:_builded.view]; // obj with my tableView
info = [[Info alloc] init];
[self.view addSubview:info.view]; // statusView
If you add a subview like the following, the tableView underneath would not catch the user interaction.
UITableView *testTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
testTableView.delegate = self;
testTableView.dataSource = self;
[self.view addSubview:testTableView];
UIView *statusView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 200, 200)];
statusView.backgroundColor = [UIColor redColor];
statusView.alpha = 0.8;
[self.view addSubview:statusView];
I have a class called PhotoBoothController that I use to manipulate an image using gestures. It works fine when I run it on iPhone. However when I run it on iPad, I display the PhotoBoothController inside a UIPopoverController. The image appears fine, however I can't manipulate it as my gestures don't appear to be recognized. I'm not sure how to make the UIPopoverController take control of the gestures.
I present the popovercontroller and configure the view thus:
- (void)presentPhotoBoothForPhoto:(UIImage *)photo button:(UIButton *)button {
//Create a photoBooth and set its contents
PhotoBoothController *photoBoothController = [[PhotoBoothController alloc] init];
photoBoothController.photoImage.image = [button backgroundImageForState:UIControlStateNormal];
//set up all the elements programmatically.
photoBoothController.view.backgroundColor = [UIColor whiteColor];
//Add frame (static)
UIImage *frame = [[UIImage imageNamed:#"HumptyLine1Frame.png"] adjustForResolution];
UIImageView *frameView = [[UIImageView alloc] initWithImage:frame];
frameView.frame = CGRectMake(50, 50, frame.size.width, frame.size.height);
[photoBoothController.view addSubview:frameView];
//Configure image
UIImageView *photoView = [[UIImageView alloc] initWithImage:photo];
photoView.frame = CGRectMake(50, 50, photo.size.width, photo.size.height);
photoBoothController.photoImage = photoView;
//Add canvas
UIView *canvas = [[UIView alloc] initWithFrame:frameView.frame];
photoBoothController.canvas = canvas;
[canvas addSubview:photoView];
[canvas becomeFirstResponder];
[photoBoothController.view addSubview:canvas];
[photoBoothController.view bringSubviewToFront:frameView];
//resize the popover view shown in the current view to the view's size
photoBoothController.contentSizeForViewInPopover = CGSizeMake(frameView.frame.size.width+100, frameView.frame.size.height+400);
self.photoBooth = [[UIPopoverController alloc] initWithContentViewController:photoBoothController];
[self.photoBooth presentPopoverFromRect:button.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
I thought [canvas becomeFirstResponder] might do it but it doesn't appear to make a difference.
Any advice much appreciate, thank you.
UPDATE: adding code as per comment
- (void)viewDidLoad {
[super viewDidLoad];
if (!_marque) {
_marque = [CAShapeLayer layer];
_marque.fillColor = [[UIColor clearColor] CGColor];
_marque.strokeColor = [[UIColor grayColor] CGColor];
_marque.lineWidth = 1.0f;
_marque.lineJoin = kCALineJoinRound;
_marque.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:5], nil];
_marque.bounds = CGRectMake(photoImage.frame.origin.x, photoImage.frame.origin.y, 0, 0);
_marque.position = CGPointMake(photoImage.frame.origin.x + canvas.frame.origin.x, photoImage.frame.origin.y + canvas.frame.origin.y);
}
[[self.view layer] addSublayer:_marque];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[canvas addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapProfileImageRecognizer setNumberOfTapsRequired:1];
[tapProfileImageRecognizer setDelegate:self];
[canvas addGestureRecognizer:tapProfileImageRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return ![gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]];
}
I am working on a similar application, and i can easily manipulate images on the canvas.
1) Check if the userInteractionEnabled property of the canvas is set to YES.
2) You can try adding the gestures to the ImageView's rather than the canvas. (I am guessing u want to zoom , rotate n swipe the images).
some guesses:
is this because viewDidLoad method have been called before cavas property been set? In this case, you could try to add recognizers after present popover in another method such as viewDidAppear.
I also agree that the key may be that UIPopoverController allows interaction to other views outside of the popover. So i suggest to move [canvas becomeFirstResponder]; to the end of the viewDidLoad method in PhotoBoothController and try self.view becomeFirstResponder here because you actually add recognizers to self.view.
In this code example, i am trying to produce the following view hierarchy
Window -> background image -> scroll view -> text view
All i see however is
Window -> background image
What am i missing please?
-(void) viewWillAppear:(BOOL)animated {
UIScrollView *scrollWindow = [[UIScrollView alloc]
initWithFrame:CGRectMake(30, 30, 440, 212)];
UITextView *scrollableText = [[UITextView alloc] init];
[scrollableText setEditable:NO];
[scrollableText setText:#"Why, hello there"];
[scrollWindow addSubview:scrollableText];
UIImage *backgroundImage = [[UIImage alloc] initWithCGImage:
[UIImage imageNamed:#"about_bg.png"].CGImage];
UIImageView *backgroundView = [[UIImageView alloc]
initWithImage:backgroundImage];
[backgroundView addSubview:scrollWindow];
[[self view] addSubview:backgroundView];
}
Andrew is right about not making the scroll view a subview of the background UIImageView view. But the scroll view is invisible. Only its content (scrollableText) will show. And you haven't set scrollableText's frame, so it's effectively invisible too. Init like so:
[scrollableText setEditable:NO];
[scrollableText setText:#"Why, hello there"];
[scrollableText setFrame:CGRectMake(0, 0, 100, 100)];
And you should see it.
What you need is this hierarchy:
Window
background image view
scroll view
text view
Try adding two subviews to your window, not shove them all as subviews into each other.''-
- (void) viewWillAppear:(BOOL)animated {
UIScrollView *scrollWindow = [[UIScrollView alloc] initWithFrame:CGRectMake(30, 30, 440, 212)];
UITextView *scrollableText = [[UITextView alloc] init];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"about_bg.png"]];
scrollableText.editable = NO;
scrollableText.text = #"Why, hello there";
[scrollWindow addSubview:scrollableText];
[self.view addSubview:backgroundView];
[self.view addSubview:scrollWindow];
}