Unknown imageview in uiscrollview - ios

I simply added new uiscrollview from interface builder and in viewDidLoad method I am getting its subview and printing it on console. It shows two image views. I can't figure it out where did they come from.
NSArray * views = [friendScrollView subviews];
NSLog(#"views are %#", [views description]);
In console:
views are (
"<UIImageView: 0x1b82f0; frame = (805 203; 7 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x1b6cb0>>",
"<UIImageView: 0x17b1d0; frame = (805 203; 7 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x1bdbd0>>"
)
When I remove them they don't even remove from scroll view.
any idea?

These image views are the horizontal and vertical scroll indicator images. They are present by default when you create the UIScrollView instance.
The iOS HIG guidelines for UIScrollView specify
When a scroll view first appears—or when users interact with it—vertical or horizontal scroll indicators flash briefly to show users that there is more content they can reveal.
This is a best practice recommended to be followed to ensure a good user experience. Hence they should not be removed. If at all it is required that the scroll indicators are not to be shown then the scroll view provides properties to achieve this programmatically. Set the required property to NO
showsHorizontalScrollIndicator
showsVerticalScrollIndicator

They are the vertical and horizontal scroll indicators and they are not supposed to be removed
UIKIT_CLASS_AVAILABLE(2_0) #interface UIScrollView : UIView <NSCoding> {
...
UIImageView* _verticalScrollIndicator;
UIImageView* _horizontalScrollIndicator;

Have you tried the following:
for (UIView *v in friendScrollView.subviews)
{
[v removeFromSuperview];
}
Also use isKindOfClass:[UIImageView class] to only remove imageviews from scrollview in case you have subview of friendScrollView other than imageviews.

Related

add sub views into UICollectionViewCell's contentView via xib or storyboard

I know there is a post:adding to UICollectionViewCell contentView via nib asking this, but the answer is not correct. Dragging a UILabel directly into a cell's xib, the Label will be added into cell itself, not its contentView:
(lldb) po self.subviews
<__NSArrayM 0x7fa9b1c58a20>(
<UIView: 0x7fa9b1c77540; frame = (0 0; 64 64); gestureRecognizers = <NSArray: 0x7fa9b1c66260>; layer = <CALayer: 0x7fa9b1c352f0>>,
<UILabel: 0x7fa9b1c7a880; frame = (0 15; 64 18); text = 'market share'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa9b1c6f820>>,
<UILabel: 0x7fa9b1c77c30; frame = (0 38; 64 22); text = '17.06'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa9b1c36fe0>>
)
(lldb) po self.contentView.subviews
<__NSArray0 0x7fa9b1d02740>(
)
This is still true on XCode 7, sample: https://github.com/liuxuan30/autolayoutProblemOniOS9.
So I asked it again for a good answer.
The behaviour is different from UITableViewCell, which will show up a contentView in xib directly. Not sure why Apple did this, and saying in UICollectionViewCell doc https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewCell_class/:
To configure the appearance of your cell, add the views needed to present the data item’s content as subviews to the view in the contentView property. Do not directly add subviews to the cell itself.
After contacting Apple's technical support, they told me it will be added in cell's contentView if it's via xib, but won't if I program it, unless I manually add them as cell.contentView's subView.
One thing to mention is that, if we add sub views via xib but it does not belongs to contentView, we need to delete the view on xib and drag a new UICollectionViewCell onto xib. The contentView will not show up on xib, this is different from UITableViewCell.

Create border between pages with UIScrollView

I am trying to create a black border between views when users scroll pages I am using UIPageControl and UIScrollView, something like this pictures :
does anybody know how to do this !?
Just set your scroll view's background to [UIColor black] and set image frames like this:
NSArray *images = ...//your array of UIImage
CGFloat blackSpaceWidth = 20;
for(int i=0; i<images.count; i++){
UIImageView *imageView = [[UIImageView alloc] initWithImage:images[i]];
imageView.frame = CGRectMake((self.view.frame.size.width + blackSpaceWidth) * i, 0, self.view.frame.size.width, self.view.frame.size.height);
scrollView.addSubview(imageView);
}
If you are using pagination in your scroll view increase its frame width by blackSpaceWidth.
you can use CollectionView
1- make cell width 320 + 20px (border width) and cell height equal to screen height
2- set cell background with black color
3- add imageView constraints in this cell if you are using auto layout
4- implement CollectionView datasource
I guess it is pretty simple.All you need to do is left spacing between views in scrollview. Suppose you have set frame of first view like this -
[[UIView alloc] initWithFrame:CGRectMake(0,0,320,self.view.frame.size.height)];
for next view declare your frame for view like this -
[[UIView alloc] initWithFrame:CGRectMake(0,320+spacing,320,self.view.frame.size.height)];
and obviously set scrollview background color to black.

Why is my UIView's frame changing unexpectedly after the embedded UITableView is interacted with?

Consider the following UIView "MainView":
The view includes a Container View which in turn houses a UITableView controller. The container view's y coordinate starts just beneath the gradient bar. The UITableView includes the section footer at very bottom with the 'STU' label and 'chart' button.
When the UIView loads, and up-to-and-until any interaction with the tableView, MainView's dimensions are:
Frame: 0.000000x, 0.000000y, 568.000000w, 268.000000h
I have a delegate protocol set up such that tapping the chart button in the tableView will create a new view in MainView for a shadow effect via a method performing:
CGRect newFrame = self.view.frame; // self = MainView
newFrame.size.width = 100;
newFrame.size.height = 50;
UIView *backgroundShadowView = [[UIView alloc] initWithFrame:newFrame];
backgroundShadowView.backgroundColor = [UIColor blackColor];
// Do Animation
The important part above is the 'newFrame' CGRect. For some reason after interacting with the table view by tapping the chart button, or even scrolling or tapping a row, self.view.frame suddenly has the following dimensions:
Frame: 0.000000x, 52.000000y, 568.000000w, 268.000000h
And so the shadow view appears as follows, with a y origin much farther down than where it would be expected to start, just above the gradient bar.
I've adjusted the width and height of the "shadowview" for this question; normally it would be 568x268, but would extend 52 units off screen on the bottom because of this issue.
52 units is exactly the height of the statusbar (20) + navigationbar_in_landscape (32).
Of course I could manually adjust the frame dimensions, but I do not want to. I want to know why the view's frame is changing unexpectedly.
For the life of me, I cannot figure out why the view becomes suddenly offset. Any help is appreciated!!
Two comments.
(1)
This code was probably always wrong:
CGRect newFrame = self.view.frame; // self = MainView
newFrame.size.width = 100;
newFrame.size.height = 50;
UIView *backgroundShadowView = [[UIView alloc] initWithFrame:newFrame];
You surely want to define backgroundShadowView's frame in terms of self.view's bounds, not its frame as you are doing in the first line here.
(2)
The change in self.view.frame is probably illusory. You are probably checking this initially in viewDidLoad. But that is too soon; the view has not yet been added to the interface, and so it has not yet been resized to fit the surroundings.

UIButton in scrollView unresponsive when outside initial frame

I have a very long view (>2000 pixels) created in a xib. This xib is loaded and then, inside it's ViewController I switch the root view for a scroll view (I want that 2000 pixels to scroll);
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *view = self.view;
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:self.view.frame];
scroll.contentSize = self.view.bounds.size;
self.view = scroll;
[scroll addSubview:view];
}
The long view has a button but it does not fire if it's placed outside the top of the long view (i.e. outside the initial screen frame).
This post seems similar but is slightly different as that SO user is extending the size of the scroll view dynamically. In this case, the scroll view of fixed size (full screen) but I can't hit things in my xib that are outside of the initial frame. During debug, I can see the frame of both the scroll view and content view are set (and long)...
<UIView: 0x946db50; frame = (0 0; 320 2320); autoresize = W+H; layer = <CALayer: 0x946db20>>
<UIScrollView: 0x9077e10; frame = (0 0; 320 2320); clipsToBounds = YES; gestureRecognizers = <NSArray: 0xb388bd0>; layer = <CALayer: 0x9276f60>; contentOffset: {0, 0}>
How can I ensure that taps are making it to controls scrolled into view?
Through trial and error I fixed this, but I'm not sure why it works. In the code above, I init the UIScrollView to have the same size frame as the content view (which actually doesn't make sense, not sure why it scrolls at all).
Instead, I got it working to sizing to the screen (since it will be full screen):
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
And now it all works swimmingly. Odd; would love to understand why this is.
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
this will create a scrollView to the match the actual view of view Controller then
UIView *newView=[[UIView alloc] initWithFrame:CGRectMake(0,0,320,2320)];
[scrollView addSubview:newView];
//u can also create this view from your long view in story board, never use the self.view inside scroll this make Ur hierarchy critical add on more long view inside the controller then refer that view to new instance in view-controller then use here
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, newview.frame.size.height);
then set
OLD answer
Set contentsize property of ur scroll view to macth the height of ur scroll view and width of your view inside scroll view...

what's wrong with this assign?

I am using GMGridView in my project. And in - (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInteger)index method, i write a snippet which is out of my expectation. The snippet is as follows:
if (!cell)
{
cell = [[GMGridViewCell alloc] init];
ThumbImageView *view = [[ThumbImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
[view setBackgroundColor:DEFAULT_BACKGROUND_COLOR];
[view setImage:[UIImage imageWithContentsOfFile:path]];
view.userInteractionEnabled = YES;
view.layer.shadowOffset = CGSizeMake(8, 8);
view.layer.shadowOpacity = 0.5;
NSLog(#"view frame width:%f,height:%f",view.frame.size.width,view.frame.size.height);
cell.contentView = view;
NSLog(#"cell.contentView frame width:%f,height:%f",cell.contentView.frame.size.width,cell.contentView.frame.size.height);
}
when it runs the output is as follows:
2013-06-03 11:02:05.508 XXX[71692:707] view frame width:115.000000,height:180.000000
2013-06-03 11:02:05.511 XXX[71692:707] cell.contentView frame width:0.000000,height:0.000000
why assign view to cell.contentView, cell.contentView.frame.size still be zero? and also cell.contentView can display the image properly. what's the reason? I am totally confused:(.
Check the docs:
contentView
Returns the content view of the cell object. (read-only)
#property(nonatomic, readonly, retain) UIView *contentView
contentView is a readonly property. You can't assign it.
The problem is probably that you've created new views, and you're looking at the frame of one of those views before the run loop has reached its layout phase.
When you create the GMGridViewCell, it starts with a default frame and bounds of CGRectZero. When you set its content view, it sets the content view's frame to its (the cell's) bounds. So even though you set the content view's frame directly using initWithFrame:, the frame gets changed to CGRectZero when you set the view as the cell's content view.
Since the cell isn't a subview of the grid view yet, there's no way to ask the grid view to lay out the cell by the time you're trying to log the content view's frame. If the grid view is using a constant size for all cells, and you know what that size is, you could manually set the cell to that size before setting the cell's content view. Otherwise, you need to wait until after the grid view's layoutSubviews method has run to check the content view's frame.

Resources