I have a UIScrollView, created programmatically, inside of a UIView. What do I need to do to ensure that I can use the delegate method scrollViewDidEndDecelerating?
Here's what I have set up, please assume that within the UIScrollView, that there are three UIImageViews. When the page first loads, I am looking at the center UIImageView and I can scroll once backwards or once forwards. The reason why I need this delegate method is because I intend to use it to calculate which UIImageView I am currently looking at.
ViewController.h
#interface ViewController : UIViewController <UIScrollViewDelegate>
ViewController.m
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.pagingEnabled = YES;
[self.view addSubview: scrollView];
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"scrollViewDidEndDecelerating");
}
Add
scrollView.delegate = self
after the scroll view initialization.
In your delegate method, you can test each uiimageview center to see Which one match the uiview center, That's the uiimageview you are looking at.
Related
I have an UIScrollview with large content in horizontal. Now I want to drag a UIImageView upto the end of the UIScrollView. For that i'm using the following code.
- (void) setUpLeftGesture{
_leftControlImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 0, 80, 25)];
[_leftControlImageView setBackgroundColor:[UIColor yellowColor]];
[_leftControlImageView setImage:[UIImage imageNamed:#"marker_left_normal"]];
//add gesture events
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSelector:)];
[_leftControlImageView addGestureRecognizer:panGestureRecognizer];
[_leftControlImageView setUserInteractionEnabled:YES];
[scrollView addSubview:_leftControlImageView];
}
-(void)handleLeftSelector:(UIPanGestureRecognizer *)panGestureRecognizer{
CGPoint point = [panGestureRecognizer locationInView:self];
_leftControlImageView.center = point;
}
When i execute the above code I can drag the _leftControlImageView (my UIImageView) is moving fine within the screensize.
If i try to drag to the end of the UIScrollView, the UIImageView not dragging. I again gets back to the previous position. I don't have idea why it's happened.
Thanks in advance. Can anyone please provide any suggestions to drag a view upto the end of the UIScrollview.
If you want to drag a view upto the end of the UIScrollView. Please make sure your view (CustomView) is extended to the UIScrollView or not. I think UIPanGestureRecognizer will allow us to perform Drag and Drop within it's super class.
So Change your super class from UIView to UIScrollView, As like this.
#interface CustomView : UIView
to
#interface CustomView : UIScrollView
By doing so you can drag a UIView upto the end of the UIScrollView.
Add imageview in your content view not in scrollview.
I have a very simple UIView, that is only drawing a triangle. It implements a UIView drawRect method that is drawing a figure. It is working fine on iOS7, but when I run the same code on iOS8 it is not even called. Any ideas what has changed on iOS8? My code in nutshell:
#interface MyView : UIView
#end
#implementation MyView
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// draw things
}
#end
myView = [MyView new];
[self addSubview:myView];
Update
My view hierarchy: UIViewController View->Custom UILabel->MyView
It is an error message bubble, and my view is a beak pointing to something.
I have used a new UI debugging tool, but it is not visible there. Init method is called, drawRect is not. Something must have changed in iOS8, because iOS7 is calling drawRect.
Update 2
Of course I'm using constraints (and Masonry pod), and this is why I did not specify the frame.
[myView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(make.superview.mas_bottom);
make.centerX.equalTo(make.superview);
make.width.equalTo(#10.0f);
make.height.equalTo(#5.0f);
}];
I have also tried adding [myView setNeedsDisplay] in various places, but it didn't help.
Problem finally solved. I'm not sure what exactly caused the issue (Masonry [constraints framework] or iOS8 changes to UILabel), but the solution was to change the view hierarchy. I created another UIView that contains both UILabel and my UIView (drawn beak) instead of adding the UIView to UILabel as subview. Now drawRect method is called both on iOS7 and iOS8.
Previous hierarchy:
UIViewController View->Custom UILabel->MyView
New hierarchy:
UIViewController View->Container UIView->Custom UILabel & MyView
To sum up, if your drawRect method is not called on iOS8, and you are adding some UIView to UILabel as subview, try to use some container which will contain both UIView and UILabel.
make sure that myView's superview property clipToBounds = NO, and that myView rect is on screen
There is an important detail missing in your approach. You need to specify a frame that determines the origin and size of your view. This can be done with the initWithRect method of UIView, or you can set the frame after allocation/initialization. Since you have a custom init method already I would do the following:
myView = [MyView new];
myView.frame = CGRectMake(0.0,0.0,100.0,100.0);
[self addSubview:myView];
This will draw your custom view with an origin point of (0.0,0.0) and a width and height of 100.0.
Furthermore, adding a call to setNeedsDisplay should force the drawRect method to be called if you are still having trouble:
[myView setNeedsDisplay];
I have a view controller with a UIScrollView embedded as a sub view. I embed it as follows:
CaptionViewController : UIViewController
Inside ViewDidLoad
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
scrollView.contentMode = (UIViewContentModeScaleAspectFit);
scrollView.contentSize = CGSizeMake(3200, 320);
scrollView.pagingEnabled = YES;
[self.view addSubview:scrollView];
Next I'm trying to wire up the scrollViewDidScroll event so I can execute some code each time the user swipes the scroll view. However, I can figure out how to access this event. I think the answer lies in delegation somehow. I tried importing UIScrollView.h and setting the scrollView delegate to the CaptionViewController as follows:
[scrollView setDelegate:self]
Still I cannot access scrollViewDidScroll. Can someone please point me in the right direction?
In addition to setting the delegate of the scroll view, you have to implement the delegate method in your CaptionViewController.m.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// handle scroll event
}
Also make sure your CaptionViewController conforms to the UIScrollViewDelegate protocol. In the .m file:
#interface CaptionViewController () <UIScrollViewDelegate>
#end
There is no need to import UIScrollView.h. You get this already.
CustomView *customView = [...];
[self.view addSubview:customView];
I need to detect in my CustomView class when it is added in other views or when my superview changes.
You can use willMoveToSuperview: and didMoveToSuperview to detect when the view is moved around. layoutSubviews will be called when the superview changes frame.
For a UIView use - (void)didMoveToSuperview
For a UIViewController use -(void)viewWillAppear:(BOOL)animated
also assign THE TAG of Customview before addsubview and the detect by Particular TAG.
My app is building purely programmatically on UITabBarController above a UINavigationController, which are both declared in my AppDelegate. Inside my navigationcontroller, I'm showing a UIViewController, a custom class. This custom class should show a custom UIView in a UIScrollView and a UIPageControl.
Heres my problem:
self.view seems to create an EXC_BAD_ACCESS error when I call it without declaring self.view = [[UIView alloc] init] (or similar). I was wondering if this was a problem with -(void) loadView but seems like it produces the same error in -(void)viewDidLoad. So I basically had to use self.view = scrollView to even show my scrollView, considering [self.view addSubview:scrollView] produced an error. My UIPageControl should stay on the page all the time, and actually be another part of the view than the UIScrollView. So I tried to add a container-view like this
Code:
container = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,0,0)];
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
// EDIT: ofcourse, I'm also resizing the frame with [scrollView setContentSize:] later, but this is farfetched code to add here.
[container addSubview:scrollView];
self.view = container;
Unfortunately, it seems that I don't get any result at all, and what appears is just an empty view. However, if I add a UILabel or similar, it shows:
[container addSubview:[[UILabel alloc] initWithFrame:CGRectMake(50,50,50,50)]]; // entered above or beneath the addSubview:scrollView line.
My question is: Why doesn't my scrollView appear in the UIView container?
I've noticed that some tutorials say that scrollView must have a delegate, and I agree with the logic - however I can't seem to find out how I set that delegate when I am in my CustomUIViewController-class instead of my AppDelegate.
after you change the UIScrollView size you should use:
[scrollView setNeedsDisplay:YES];
also you implement Delegates the same way you do in other classes:
.h:
#interface MyClass : NSObject <UIScrollViewDelegate>
Okay, the problem seemed to be the initialization - I didn't realize that frame and content was two different things. Seems like the frame that is initializing the view should be whatever size the view should fill, while content is the actual content of whatever should be scrolled. So when I was having problems with user interaction, it was really this.
The problem of why it didn't show in the first place was (stupid.) that the frame was initially, and never changed from, 0,0 so I really lied in my first post.
Thanks to UIScrollView and PageControl: space between views who solved my problem with user interaction.
My steps was to backtrace from self.view:
NSLog(#"%f\n%f",
((UIScrollView*) [[self.view subviews] objectAtIndex:0]).frame.size.width,
((UIScrollView*) [[self.view subviews] objectAtIndex:0]).frame.size.height);
when I realized these were 0 and 0, fixing the problem wasn't too hard :) thanks though, for your efforts Kristian.