addSubview change the index of one object in scroll.subviews - ios

I add objects in UIScrollView inside cycle FOR, but after the second interaction the index of subviews change.
When i create the ScrollView:
scroll.subviews :(
"<UIImageView: 0x147aeee0; frame = (1017 186; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x147aef50>>",
"<UIImageView: 0x147aefa0; frame = (1019 184; 5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x147af010>>"
)
After i have the cycle FOR with [scroll addSubview:btn];
First
scroll.subviews :(
"<UIImageView: 0x147aeee0; frame = (1017 186; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x147aef50>>",
"<UIImageView: 0x147aefa0; frame = (1019 184; 5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x147af010>>",
"<ContentButton: 0x13fdc610; baseClass = UIButton; frame = (15 10; 221 173); opaque = NO; tag = 1; layer = <CALayer: 0x1034cc00>>"
)
Second (change last object to index 0)
scroll.subviews :(
"<ContentButton: 0x13fdc610; baseClass = UIButton; frame = (15 10; 221 173); opaque = NO; tag = 1; layer = <CALayer: 0x1034cc00>>",
"<UIImageView: 0x147aefa0; frame = (1019 184; 5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x147af010>>",
"<UIImageView: 0x147aeee0; frame = (1017 186; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x147aef50>>",
"<ContentButton: 0x105ddf70; baseClass = UIButton; frame = (246 10; 221 173); opaque = NO; tag = 149; layer = <CALayer: 0x105523e0>>"
)
Third and so on, the object will add normally (in last index)
scroll.subviews :(
"<ContentButton: 0x13fdc610; baseClass = UIButton; frame = (15 10; 221 173); opaque = NO; tag = 1; layer = <CALayer: 0x1034cc00>>",
"<UIImageView: 0x147aefa0; frame = (1019 184; 5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x147af010>>",
"<UIImageView: 0x147aeee0; frame = (1017 186; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x147aef50>>",
"<ContentButton: 0x105ddf70; baseClass = UIButton; frame = (246 10; 221 173); opaque = NO; tag = 149; layer = <CALayer: 0x105523e0>>",
"<ContentButton: 0x13f1dc80; baseClass = UIButton; frame = (477 10; 221 173); opaque = NO; tag = 3; layer = <CALayer: 0x13f1dd20>>"
)
The problem is in the second interaction, so why the last object (ContentButton) was in the index 2 and change into index 0?
for (obj * objScroll in arrayChaObj)
{
// UIButton
ContentButton * btn = [[ContentButton alloc] initWithFrame:CGRectMake(btContentPosXChaObj,
10,
imgButtonScroll.size.width,
imgButtonScroll.size.height)];
btContentPosXChaObj += 10 + imgButtonScroll.size.width;
[scroll addSubview:btn];
NSLog(#"scroll.subviews :%#",scroll.subviews);
[scroll setContentSize:CGSizeMake(btContentPosXChaObj, imgButtonScroll.size.height+10)];
}

This is just a wild guess.
What happens when you call setContentSize: for the first time? Well, the two image views end up outside the content region. They won't be ever displayed.
I guess the scrollview then optimizes the order of subviews and puts the invisible ones to the end which can probably improve its clipping (redrawing) functionality.
Currently I don't have the time to check this and experiment but it's a reasonable explanation for me.

Related

What is this firstObject of my custom UIScrollview?

I have a custom UIScrollView, and I add 5 imageView as its subviews.However, after I log its subviews array , it has 6 children!! I use storyboard to add the scrollview add drag its IBOutlet. I have no idea where the firstObject come from?
- (void)configViews {
NSInteger launchImageCount = 5;
CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
CGFloat screenHeight = CGRectGetHeight([UIScreen mainScreen].bounds);
self.scrollView.contentSize = CGSizeMake(screenWidth * launchImageCount, screenHeight);
self.scrollView.clipsToBounds =YES;
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
self.scrollView.showsHorizontalScrollIndicator = NO;
for(int i = 0; i < launchImageCount; i++) {
NSString *imageName = [NSString stringWithFormat:#"B0%lu.jpg",(long)(i+1)];
CGRect rect = CGRectMake(screenWidth*i, 0, screenWidth, screenHeight);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect];
imageView.image = [UIImage imageNamed:imageName];
[self.scrollView addSubview:imageView];
}
NSLog(#"subviews :%#",self.scrollView.subviews);
self.pageControl.numberOfPages = launchImageCount;
}
Log:
2015-09-26 17:24:29.626 CustomTableView[60621:7911319] subviews :(
"<UIImageView: 0x7f9680f30760; frame = (234.5 118; 2.5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680f2f6c0>>",
"<UIImageView: 0x7f9680e25a30; frame = (0 0; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680e19290>>",
"<UIImageView: 0x7f9680d5ab30; frame = (375 0; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680d5a7b0>>",
"<UIImageView: 0x7f9680e26af0; frame = (750 0; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680e26280>>",
"<UIImageView: 0x7f9680e2a450; frame = (1125 0; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680e2a1b0>>",
"<UIImageView: 0x7f9680e2e1b0; frame = (1500 0; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7f9680e2df90>>"
)
The UIScrollView has two default UIImageView to show you your scroll bars.
You probably enabled a horizontal/vertical scroll indicator, and that is the reason you see this extra UIImageView child.

Reduce font size for UITableViewRowAction

When looking at the Apple "Mail" app, the fonts of the row actions is around 20% smaller than the default ones. How can I get the same font size in swift?
Here is the view hierarchy:
<UITableViewCellDeleteConfirmationView: 0x14ed4edf0; frame = (320 0; 254 77.5); clipsToBounds = YES; autoresize = H; layer = <CALayer: 0x170620340>>
| <_UITableViewCellActionButton: 0x14ed190f0; frame = (155 0; 99 77.5); opaque = NO; autoresize = H; layer = <CALayer: 0x170622a00>>
| | <UIButtonLabel: 0x14ed36920; frame = (15 28; 69 21.5); text = 'Delete'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17029ce30>>
| <_UITableViewCellActionButton: 0x14ed50380; frame = (71.5 0; 83.5 77.5); opaque = NO; autoresize = H; layer = <CALayer: 0x170436ec0>>
| | <UIButtonLabel: 0x14ed45a50; frame = (15 28; 53.5 21.5); text = 'Edit'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17009d4c0>>
| <_UITableViewCellActionButton: 0x14ed5a320; frame = (0 0; 71.5 77.5); opaque = NO; autoresize = H; layer = <CALayer: 0x170439940>>
| | <UIButtonLabel: 0x14ed422b0; frame = (15 28; 41.5 21.5); text = 'More'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170296760>>
Can I access the UIButtonLabels somehow?
Tried so far:
I tried changing the appearance, but it seems not defined for this element.
Writing an extension for UILabel that changes font on layoutSubviews worked, but it also changed all other UILabels.
Objc code
+ (NSArray*)findAllButtonLabelFromCell:(UITableViewCell*)cell {
NSMutableArray* buttonLabels = [[NSMutableArray alloc]init];
[self addButtonLabelToArray:buttonLabels view:cell];
return buttonLabels;
}
+ (void)addButtonLabelToArray:(NSMutableArray*)arr view:(UIView*)view {
//For pass Apple examine
//contact the name in runtime
NSString* prefix = #"UIButton";
NSString* suffix = #"Label";
NSString* name = [prefix stringByAppendingString:suffix];
for (UIView* subView in view.subviews) {
if ([subView isKindOfClass:NSClassFromString(name)]) {
[arr addObject:subView];
}
[self addButtonLabelToArray:arr view:subView];
}
}
and you should access the return array elements with UILabel

UITouch is not working with ios8

I am working on one app. Which capture images continuously, there is one button to stop capturing. But the problem is that button targeted method is not being called. Even when I clicked on the screen anywhere it didn't detect touch or gesture. I have implemented gesture and touch delegate methods to check. Capturing image is not on main thread so main thread is free. So I am not able to find the reason why view not able to detect the touch. There are almost 6-7 button on that particular view, none of them trigger their method. While working with ios7 its running properly, It will detect touch and button targeted method trigger also.
I have thought that there should be any-view that will be overlap those button so i print the stake of subview , which is as below.Button which stop capturing is with text "START". I have just share stake after START button only as i think in stake the last item will be on top in view.
<UIButtonLabel: 0x15dfb0d0; frame = (5 14; 41 16); text = 'START';
opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer:
0x15dfb190>>
<UIButton: 0x15e8c590; frame = (63 7; 36 32); opaque = NO; autoresize
= RM+BM; layer = <CALayer: 0x15e8c690>>
<UIButtonLabel: 0x15df0400; frame = (15 10; 6 12); text = '0'; opaque
= NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d98db0>>
<UIImageView: 0x15e97c00; frame = (-295 -272; 1557 1568);
clipsToBounds = YES; hidden = YES; autoresize = W+H;
autoresizesSubviews = NO; layer = <CALayer: 0x15ea2920>>
<_UILayoutGuide: 0x15e90ba0; frame = (0 0; 0 0); hidden = YES; layer =
<CALayer: 0x15ea2b10>>
<_UILayoutGuide: 0x15e86120; frame = (0 1024; 0 0); hidden = YES;
layer = <CALayer: 0x15e6fc40>>
<MPVolumeView: 0x15db7840; frame = (18 340; 284 23); alpha = 0; opaque
= NO; layer = <CALayer: 0x15dbd2e0>>
<UILabel: 0x15daee40; frame = (0 0; 0 0); text = 'No Volume
Available'; opaque = NO; autoresize = W+BM; userInteractionEnabled =
NO; layer = <_UILabelLayer: 0x15dd5be0>>
<MPButton: 0x15dd5e00; baseClass = UIButton; frame = (131.5 2.5; 21.5
18); alpha = 0; opaque = NO; autoresize = LM+BM; layer = <CALayer:
0x15dd6030>>
<UIImageView: 0x15de0c30; frame = (-39.25 -41; 100 100); alpha = 0;
opaque = NO; userInteractionEnabled = NO; tag = 1886548836; layer =
<CALayer: 0x15ea5330>>
<UIImageView: 0x15ea5790; frame = (0 0; 21.5 18); clipsToBounds = YES;
opaque = NO; userInteractionEnabled = NO; layer = <CALayer:
0x15ea5810>>
I am using auto-layout. Please can you help me to handle this problem. I am new with auto-layout. so anything that i can change in storyboard get this problem solved please let me know. Thanks in advance.
Thanks for all your answers. I got solution by moving irate code from +initialize method of AppDelegate to didFinishLaunchingWithOptions method. My iRate get initialized and configure but don't show popup. May be that's why i was not able to perform any touch on screen.

isKindOfClass grab tag

I just want to grab the button tag 1~ 5 in ScrollView, other data do not need to grasp
(void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [weekscroll subviews];
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
NSLog(#"%d",view.tag);
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (wScrollObjWidth);
}
}
NSLog(#"subviews = %#",subviews);
[weekscroll setContentSize:CGSizeMake((wNumImages * wScrollObjWidth), [weekscroll bounds].size.height)];
}
subviews = (
"<UIImageView: 0x1ba330; frame = (313 61; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x1bac00>>",
"<UIImageView: 0x1bc900; frame = (315 59; 5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x1bdde0>>",
"<UIButton: 0x1bd380; frame = (0 1; 50 66); opaque = NO; layer = <CALayer: 0x1bd410>>",
"<UIButton: 0x1bd690; frame = (50 0; 50 66); opaque = NO; layer = <CALayer: 0x1bd720>>",
"<UIButton: 0x1bd9a0; frame = (100 0; 50 66); opaque = NO; layer = <CALayer: 0x1bda30>>",
"<UIButton: 0x1bc570; frame = (150 0; 50 66); opaque = NO; layer = <CALayer: 0x1bc600>>",
"<UIButton: 0x1beaa0; frame = (300 0; 50 66); opaque = NO; tag = 1; layer = <CALayer: 0x1beb30>>",
"<UIButton: 0x1bff40; frame = (350 0; 50 66); opaque = NO; tag = 2; layer = <CALayer: 0x1c0920>>",
"<UIButton: 0x1c0e60; frame = (400 0; 50 66); opaque = NO; tag = 3; layer = <CALayer: 0x1c0ef0>>",
"<UIButton: 0x1c1430; frame = (450 0; 50 66); opaque = NO; tag = 4; layer = <CALayer: 0x1c14c0>>",
"<UIButton: 0x1c1a00; frame = (500 0; 50 66); opaque = NO; tag = 5; layer = <CALayer: 0x1c1a90>>",
"<UIButton: 0x1cb340; frame = (1800 0; 50 66); opaque = NO; layer = <CALayer: 0x1cb3d0>>",
"
)UIImageView: 0x1ba330; frame = (313 61; 7 5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer =
As per printed log, only UIButtons are having tags and in sample code you are working on UIImageView, so use given code as per your requirement.
I have modified your code as below, just check it out.
for (id objView in subviews)
{
if ([objView isKindOfClass:[UIImageView class]])
{
UIImageView *imgView = (UIImageView*) objView;
if (imgView.tag > 0)
{
NSLog(#"%d",imgView.tag);
CGRect frame = imgView.frame;
frame.origin = CGPointMake(curXLoc, 0);
imgView.frame = frame;
curXLoc += (wScrollObjWidth);
}
}
}
Or if you want to grab only UIButtons,
for (UIButton *btnView in subviews)
{
if ([btnView isKindOfClass:[UIButton class]] && btnView.tag > 0)
{
NSLog(#"%d",btnView.tag);
CGRect frame = btnView.frame;
frame.origin = CGPointMake(curXLoc, 0);
btnView.frame = frame;
curXLoc += (wScrollObjWidth);
}
}
You want the button with tags greater than 0 right.. then why are you checking for [UIImageView class].. ?
your condition to find Buttons with tag greater than 0 should be :
if ([aView isKindOfClass:[UIButton class] && (aView.tag > 0)]) {
}

How does view layering affect a views positioning?

This question has been re-written, since I think it has more to do with views and layers than the original 'Finding the center of a tableview'. Also in hope of finding another answer.
In question, is a set of 4 views to show activity, in a tableview, in a tab bar.
The code of:
NSLog(#"view.center: %#", self.view.center);
NSLog(#"view.frame: %#", self.view.frame);
Produces, on first display of 'loading':
view.center: {160, 250}
view.frame: {{0, 20}, {320, 460}}
For 2nd (and subsequent) displays: (after a pop up date picker)
view.center: {160, 205.5}
view.frame: {{0, 0}, {320, 411}}
Self (ListViewController) is subclass of UITableViewController. So, the height of the view (or tableview) frame is changing. Why?
I've been exploring and found this info in the debugger, that seems relevant.
--- Before ---
[self parentViewController]:
<UITabBarController: 0x6e115a0>
[[self parentViewController] view]:
<UILayoutContainerView: 0x6e1b750; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x6e0c8f0>>
self: <ListsViewController: 0x6e13730>
[self tableView]:
<UITableView: 0x71e4000; frame = (0 20; 320 460); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x6834db0>; contentOffset: {0, 0}>
[[self view] subviews]: (array)
<UIImageView: 0x6825e30; frame = (0 453; 320 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x6835a90>>,
<UIImageView: 0x68314e0; frame = (313 411; 7 20); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x683d120>>,
<UIView: 0x6a054f0; frame = (0 0; 320 460); alpha = 0.4; tag = 12; layer = <CALayer: 0x6a07840>>,
<UIView: 0x6a04c60; frame = (110 155.5; 100 100); alpha = 0.6; tag = 13; layer = <CALayer: 0x6a073c0>>,
<UILabel: 0x6a07480; frame = (110 200.5; 100 50); text = 'Loading ...'; clipsToBounds = YES; userInteractionEnabled = NO; tag = 14; layer = <CALayer: 0x6a065b0>>,
<UIActivityIndicatorView: 0x6a07a80; frame = (140 167.5; 40 40); tag = 15; layer = <CALayer: 0x6a07b40>>
--- After datepicker ---
[self parentViewController]:
<UITabBarController: 0x6e115a0>
[self parentViewController] view]:
<UILayoutContainerView: 0x6e1b750; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x6e0c8f0>>
self: <ListsViewController: 0x6e13730>
[self tableView]:
<UITableView: 0x71e4000; frame = (0 0; 320 411); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x6834db0>; contentOffset: {0, 0}>
[[self view] subviews]:
<DetailTableViewCell: 0xb642120; baseClass = UITableViewCell; frame = (0 369; 320 44); autoresize = W; layer = <CALayer: 0xb642230>>,
<DetailTableViewCell: 0xb643850; baseClass = UITableViewCell; frame = (0 325; 320 44); autoresize = W; layer = <CALayer: 0xb643960>>,
<DetailTableViewCell: 0xb6435c0; baseClass = UITableViewCell; frame = (0 281; 320 44); autoresize = W; layer = <CALayer: 0xb6436d0>>,
<DetailTableViewCell: 0xb63cf30; baseClass = UITableViewCell; frame = (0 237; 320 44); autoresize = W; layer = <CALayer: 0xb63d130>>,
<DetailTableViewCell: 0x6a14050; baseClass = UITableViewCell; frame = (0 193; 320 44); autoresize = W; layer = <CALayer: 0x6a16fb0>>,
<DetailTableViewCell: 0x6a13760; baseClass = UITableViewCell; frame = (0 149; 320 44); autoresize = W; layer = <CALayer: 0x6a13870>>,
<DetailTableViewCell: 0x6a10920; baseClass = UITableViewCell; frame = (0 105; 320 44); autoresize = W; layer = <CALayer: 0x6a10010>>,
<DetailTableViewCell: 0xb63ce20; baseClass = UITableViewCell; frame = (0 60; 320 45); autoresize = W; layer = <CALayer: 0xb63c3e0>>,
<UIImageView: 0x6825e30; frame = (0 404; 320 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x6835a90>>,
<UIView: 0xb6477f0; frame = (0 0; 320 60); autoresize = W; layer = <CALayer: 0xb647820>>,
<UIImageView: 0x68314e0; frame = (313 411; 7 20); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x683d120>>,
<UIView: 0x6a098a0; frame = (0 0; 320 411); alpha = 0; tag = 9; animations = { opacity <CABasicAnimation: 0xb6279f0>; }; layer = <CALayer: 0x6a154b0>>,
<UIDatePicker: 0x6a23350; frame = (0 455; 320 216); tag = 10; animations = { position <CABasicAnimation: 0xb63bd40>; }; layer = <CALayer: 0x6a20590>>,
<UIToolbar: 0x6843f60; frame = (0 411; 320 44); opaque = NO; tag = 11; animations = { position=<CABasicAnimation: 0xb645f80>; }; layer = <CALayer: 0x6844a20>>,
<UIView: 0xb60baa0; frame = (0 0; 320 411); alpha = 0.4; tag = 12; layer = <CALayer: 0xb626af0>>,
<UIView: 0xb626b20; frame = (110 155.5; 100 100); alpha = 0.6; tag = 13; layer = <CALayer: 0xb626930>>,
<UILabel: 0xb60cfb0; frame = (110 200.5; 100 50); text = 'Loading ...'; clipsToBounds = YES; userInteractionEnabled = NO; tag = 14; layer = <CALayer: 0xb60d020>>,
<UIActivityIndicatorView: 0xb649e20; frame = (140 167.5; 40 40); tag = 15; layer = <CALayer: 0xb626960>>
You can use tableview.frame to access the origin points and it's dimensions. You can use tablview.center which is a CGPoint which gives you the center point of the object.

Resources