How can i get the content of a subview in a UiScrollview - ios

I have a UIScrollview in a tab, i added some UIView (NIB) to the UIScrollview. Each UIView has some UISwictch, labels, buttons, etc. How can i get the the label.text inside of the view added to the UIScrollview.
I tried a lot of things but i can access to the content of the UIView added to the UIScrollview.

Check with this,
for (UIView *addedView in [self.scrollView subviews])
{
for (UIView *sub in [addedView subviews])
{
if([sub isKindOfClass:[UILabel class]])
{
UILabel *myLabel = (UILabel *)sub;
NSLog(#"My label :%#",myLabel .text);
}
}
}
Here scrollView is your scroll view. It will print all label's text.
If you need to print any particular label's text. Then add a tag to it and check the tag before printing it, like if(myLabel.tag == 7)

set a unique tag for your label.
eg: label.tag = 10345 (some random number, which is a unique tag)
and you can search for the label in the parentView like this
UILabel *theLabel = (UILabel *)[parentView viewWithTag: 10345];
and then you can do what ever you want with the Label.

Step 1: Add this code in your scrollview
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTapGestureRecognizer];
Step 2: Implement this method
-(void)singleTap:(UITapGestureRecognizer *)gesture
{
// Convert gesture into view for getting subviews
CGPoint point = [gesture locationInView:mainScrollView];
UIView *tappedView = [mainScrollView hitTest:point withEvent:nil];
// Get the subviews of the view
NSArray *subviews = [view tappedView];
// Return if there are no subviews
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
NSLog(#"%#", subview);
// List the subviews of subview
[self your_method:subview];
}
}

Related

UITapGestureRecognizer for detecting which UIView was tapped on my screen

I am using UITapGestureRecognizer for detecting which UIView was tapped on my screen but for some reason it only detects the parent view tap, for example below code logs only parent views tag. How do i detect subview taps which are present on main view. Please suggest.
Inside View did load :-
UITapGestureRecognizer *viewTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(actionForViewTapped:)];
[self.view addGestureRecognizer:viewTapRecognizer];
-(void) actionForViewTapped:(UITapGestureRecognizer*)sender {
NSLog(#"view tapped");
UIView *view = sender.view;
NSLog(#"view tag is %lu", view.tag); //Always prints parent view tag.
if(view.tag == 10){
NSLog(#"tag1 tapped"); // not called
}
if(view.tag == 20){
NSLog(#"tag 2 tapped"); // not called
}
}
You can detect subview using following code, I just tested creating sample project.
-(void) actionForViewTapped:(UITapGestureRecognizer*)sender {
NSLog(#"view tapped");
UIView *view = sender.view;
CGPoint loc = [sender locationInView:view];
UIView* subview = [view hitTest:loc withEvent:nil];
NSLog(#"view tag is %lu", subview.tag); //will print Subview tag.
if(view.tag == 10){
NSLog(#"tag1 tapped");
}
if(view.tag == 20){
NSLog(#"tag 2 tapped");
}
}
A UIGestureRecognizer is to be used with a single view.
If you want to use UIGestureRecognizer you will have to create one for each view, calling the same method.

How To Access All UIButtons within a UIScrollView within a UIView?

I am using the following to try to access all the UIButtons located inside of a UIScrollView within a UIView. The problem is that the code doesn't seem to locate the buttons and set the border property.
UIView -> UIScrollView -> UIButtons.
I basically want to loop through the buttons and set the border property.
for(UIView *v in [self.viewLightLeakChoices subviews]) {
if([v isKindOfClass:[UIButton class]]) {
v.layer.borderWidth = 0;
}
}
Try this one instead
for (id obj in scrollView.subviews) {
NSString *classStr = NSStringFromClass([obj class]);
if ([classStr isEqualToString:#"UIButton"]) {
UIButton *button = (UIButton*)obj;
button.layer.borderWidth = 2.0;
button.layer.borderColor = [UIColor greenColor].CGColor;
}
}
output
Thanks for the help guys. I ended up doing a bunch of for loops to get down to the UIButtons.
for(UIView *v in [self.viewLightLeakChoices subviews]) {
if([v isKindOfClass:[UIScrollView class]]) {
for(UIView *subView in [v subviews]) {
for(UIButton *btn in [subView subviews]) {
btn.layer.borderWidth = 0;
}
}
}
}
first make sure you are getting subviews of UIScrollView because your structure is
UIView > UIScrollView> UIButton
if you have only 1 scroll view in self.viewLightLeakChoices then set your scrollview tag = 1000 and direct access your scrollview so now you dont need to use loop. and execution will be fast.
UIScrollView *scrlV = [self.viewLightLeakChoices viewWithTag:1000];
for (UIButton *btn in scrlV.subviews)
{
if ([btn isKindOfClass:[UIButton Class]]) {
btn.layer.borderWidth = 1.0;
btn.layer.borderColor = [UIColor whiteColor].CGColor;
}
}
i am unable to get i am expecting you are having scrollview -> uiview ->button
for(UIView *myview in Scrollview.subviews)
{
for ( id mybutton in myview.subviews)
{
if ([mybutton isKindOfClass:[UIButton class]])
{
UIButton *mybtn=(UIButton *)mybutton;
mybtn.layer.borderWidth=0;
}
}
}
You should have create Button class say MyButton extents UIButton, if you do this there is no need to loop through scrollview's subviews.
implement awakeFromNib method and apply border, to apply border refer this SO Post How to create border in UIButton?

How to iterate through self.superview in Xcode?

I have a class called LabelView inheriting from UIView. In the story board have a view dragged and inheriting from LabelView. Now I want to iterate through the self.superview to set the attributed text of each view. Please suggest a method to do so.
Here is my code:
int i=0;
for (UIView *view in labelView) {
if ([view isMemberOfClass:[LabelView class]]) {
[view setTag:i];
NSArray *symbols = #[#"+", #"-", #"*", #"/"];
NSString* symb = [NSString stringWithFormat:#"%#", [symbols objectAtIndex:i]];
UIFont *labelFont = [UIFont systemFontOfSize:view.bounds.size.width*0.80];
NSAttributedString *labelOperator=[[NSAttributedString alloc]initWithString:[NSString stringWithFormat:#"%#", symb]attributes:#{NSFontAttributeName: labelFont}];
CGRect textrect;
textrect.origin=CGPointMake(12, 0);
textrect.size=[labelOperator size];
[labelOperator drawInRect:textrect];
i++;
}
else{
NSLog(#"fail");
}
}
You may want to try something like this:
for (UIView *view in self.view.subviews) {
if ([view isMemberOfClass:[LabelView class]]) {
//DO WHATEVER YOU WANT
}
The above fast enumeration code iterates through all the subviews in your self.view and checks if the view is a member of your custom class which is LabelView. If it finds one, then the statements inside the if condition gets executed. Hope it helps!
The key is to go from your label view to the superview and iterate through its subviews.
for (UIView *label in labelView.superview.subviews) {
if ([label isKindOfClass:[LabelView class]]) {
// configure the label
}
}

Nested UIScrollViews

I have a mainScrollView scrolling horizontally with photos added to it and mainScrollView's contentSize is set according to the number of photos.
To achieve the effect of scrolling to the end and swiping in a UIView with display info for user, I added the overlayScrollView to mainScrollView's subviews.
overlayScrollView contains the contentView positioned outside the frame.
CGRect frame = self.mainScrollView.frame;
frame.origin.x = CGRectGetWidth(frame) * (count-1);
UIScrollView *overlayScrollView = [[UIScrollView alloc] initWithFrame:frame];
[self.mainScrollView addSubview:overlayScrollView];
// moves contentView one frame beyond
frame.origin.x = CGRectGetWidth(frame);
UIView *contentView = [[UIView alloc] initWithFrame:frame];
contentView.backgroundColor = [UIColor redColor];
[overlayScrollView addSubview:contentView];
overlayScrollView.contentSize = CGSizeMake(overlayScrollView.frame.size.width * 2, overlayScrollView.frame.size.height);
overlayScrollView.pagingEnabled = YES;
I searched through SO on nested UIScrollViews and so subclassed UIScrollView for mainScrollView with the following method:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *child in self.subviews){
if([child isMemberOfClass:[UIScrollView class]])
if(CGRectContainsPoint(child.frame, point))
return child;
}
return self;
}
But it doesn't work. My code could be wrong. hitTest did return child (overlayScrollView) but did not scroll. Any suggestions how to code this?

Remove gradient background from UIWebView?

How do remove the gradient from a UIWebView - the one that you see if you overscroll the top or bottom.
This code
webView.backgroundColor = [UIColor whiteColor];
just changes the color of the gradient, it doesn't removes it. How can this be done?
(note: not the same question as UIWebView underside)
Aha, yes terminology fail. I wouldn't call that a shadow at all, but c'est la vie. Here is my type-safe code to achieve the effect. To summarise: this will hide any image-view children of the scroll view. It's not as vulnerable to change as the (objectAtIndex:0) methods, so if Apple re-order the children of the webView control it will work fine, but still relies on the fact that the gradient effect is applied by imageviews parented to the scroll view (and that there is indeed a scrollview underpinning the web view).
{
webView.backgroundColor = [UIColor whiteColor];
for (UIView* subView in [webView subviews])
{
if ([subView isKindOfClass:[UIScrollView class]]) {
for (UIView* shadowView in [subView subviews])
{
if ([shadowView isKindOfClass:[UIImageView class]]) {
[shadowView setHidden:YES];
}
}
}
}
}
To transparent the UIWebView and remove the scrolls.
webView.opaque = NO;
webView.backgroundColor = [UIColor clearColor];
for(UIView *view in webView.subviews){
if ([view isKindOfClass:[UIImageView class]]) {
// to transparent
[view removeFromSuperview];
}
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView *sView = (UIScrollView *)view;
for (UIView* shadowView in [sView subviews]){
//to remove shadow
if ([shadowView isKindOfClass:[UIImageView class]]) {
[shadowView setHidden:YES];
}
}
}
}
for hide scroll indicators
You mean the shadow? Remove UIWebView Shadow?
The only way I found how to do this was :
for(UIView *aView in [[[webView subviews] objectAtIndex:0] subviews]) {
if([aView isKindOfClass:[UIImageView class]]) { aView.hidden = YES; }
}
It just just steps thru the subviews of UIWebView and removes the view if it is an image view.
I haven't put this in any App Store apps, so I don't know if Apple would accept it.
EDIT: Brian's link provides more details.
Using method suggested above you won't be able to edit your scroll indicator/insets later. They appear as UIImageView also, so you should check for last object:
UIView* lastView = [[subView subviews] lastObject];
for (UIView* shadowView in [subView subviews])
{
if(shadowView!=lastView) ... <-this one is a scroll
}
I was able to do this by adding white subviews to the top and bottom of the WebView’s scrollView. I control the content of the WebView, so I know that white is OK - this won’t work if you are loading arbitrary content.
// _topCover and _bottomCover are ivar UIViews
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// with cover views 300pt high, I couldn't scroll far enough to see the shadow,
// even in portrait on an iPad, which gives you the longest scroll distance
CGFloat coverage = 300;
_topCover = [[UIView alloc] initWithFrame:CGRectMake(0, -coverage, webView.bounds.size.width, coverage)];
_bottomCover = [[UIView alloc] initWithFrame:CGRectMake(0, webView.scrollView.contentSize.height, webView.bounds.size.width, coverage)];
_topCover.backgroundColor = [UIColor whiteColor];
_bottomCover.backgroundColor = [UIColor whiteColor];
// in case the webView is resized, e.g. by rotating the device
_topCover.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
_bottomCover.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
[webView.scrollView addSubview:_topCover];
[webView.scrollView addSubview:_bottomCover];
}
I run it it after the page loads so that webView.scrollView.contentSize.height will give me the correct height. I’m not sure how this will work if your pages are dynamically changing height. My page loads only once; if yours is reloading, you will want to skip running alloc/init on _topCover and _bottomCover after the first time for efficiency.
Update: I’m not sure that my use of autoresizingMask, above, is sufficient when the view rotates. You may need to put this in the UIViewController that contains your UIWebView to resize the covers after rotating:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGFloat coverage = 300;
_topCover.frame = CGRectMake(0, -coverage, self.webView.bounds.size.width, coverage);
_bottomCover.frame = CGRectMake(0, self.webView.scrollView.contentSize.height, self.webView.bounds.size.width, coverage);
}
I've built upon #damithH 's answer
#implementation UIWebView (Extensions)
- (void)setBackgroundAndShadowVisible:(BOOL)visible
{
self.opaque = !visible;
self.backgroundColor = [self.backgroundColor colorWithAlphaComponent:visible ? 1.0 : 0.0];
for(UIView *view in [self subviews])
{
if([view isKindOfClass:[UIImageView class]])
{
view.hidden = !visible;
}
if([view isKindOfClass:[UIScrollView class]])
{
UIScrollView *scrollView = (UIScrollView *)view;
for (UIView *shadowView in [scrollView subviews])
{
if ([shadowView isKindOfClass:[UIImageView class]])
{
shadowView.hidden = !visible;
}
}
}
}
}
#end
if (UIDevice.currentDevice.systemVersion.intValue < 7)
for (UIImageView *imageView in webView.scrollView.subviews)
if ([imageView isKindOfClass:[UIImageView class]] && imageView.image.size.width == 1)
imageView.hidden = YES;

Resources