Reduce font size for UITableViewRowAction - ios

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

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.

Swift isKindOfClass not work

I have a ViewController and some label and textfield for user to input, and in some point I need to loop over all textfield to collect the user's input.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.configureView()
for views in self.view.subviews {
if view is UITextField
{
println("inside")
}
println(views.description)
}
}
For this code, the "inside" never print out. But I do see some the information of views.description
<UILabel: 0x7fa4b1c7bd00; frame = (16 97; 76 21); text = 'FromDate'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa4b1c44580>>
<UILabel: 0x7fa4b1c9fd60; frame = (16 169; 82 21); text = 'ControlNO'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fa4b1c77fb0>>
>
<UITextField: 0x7fa4b1c7a050; frame = (106 95; 197 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7fa4b1c6c800>>
<UITextField: 0x7fa4b1c9c060; frame = (106 126; 197 30); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; tag = 1; layer = <CALayer: 0x7fa4b1c9c2c0>>
<_UILayoutGuide: 0x7fa4b1d11d20; frame = (0 0; 0 0); hidden = YES; layer = <CALayer: 0x7fa4b1d11e00>>
<_UILayoutGuide: 0x7fa4b1d253f0; frame = (0 0; 0 0); hidden = YES; layer = <CALayer: 0x7fa4b1d12f60>>
but if I println(views.dynamicType) I could only see ExistentialMetatype.
What is wrong in my code?
The loop variable is called views, but you test view (which is
not the loop variable and therefore identical to self.view):
for views in self.view.subviews { // "views" here
if view is UITextField { // "view" here
println("inside")
}
}
If you rename the loop variable to view
for view in self.view.subviews {
if view is UITextField {
println("inside")
}
}
then everything works as expected.
You can use isKindOfClass:
var tex = UITextField()
if tex.isKindOfClass(UITextField){
println("yes")
}
#Christian's code will work. Here is another solution.
if let view = tex as? UITextField {
// view is a UITextField
}

UIButton is unclickable after change in container height

An UIButton is contained inside a UIScrollView. I have this setup in a xib. I use a NSLayoutConstraint to change the height of the scrollview. After I click the button, the scrollview changes height, but then UIButton becomes unclickable.
Here is the code:
- (IBAction)TagPressed:(UIButton *)sender {
if (self.height.constant == 200) {
self.height.constant = 88;
}else
self.height.constant = 200;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.5f animations:^{
[self.view layoutIfNeeded];
}];
DRect(_scrollView.frame)
DRect(self.view.frame)
DRect(sender.frame)
NSLog(sender.selected ? #"Selected" : #"Not Selected");
}
Drect is a nslog for frames. So the Console out is:
2013-04-08 17:04:19.264 TouchSelectApp[93618:c07] CGRect ( 20.000000, -112.000000, 62.000000, 200.000000)
2013-04-08 17:04:19.266 TouchSelectApp[93618:c07] CGRect ( 0.000000, 300.000000, 320.000000, 88.000000)
2013-04-08 17:04:19.266 TouchSelectApp[93618:c07] CGRect ( 7.000000, 78.500000, 48.000000, 44.000000)
Output from (lldb) po [[UIApp keyWindow] recursiveDescription]
I had to add a an extra button to create a debugging stop. The button I care about is inside SelectableTag.
$0 = 0x0887e0e0 <UIWindow: 0x7197a90; frame = (0 0; 320 568); autoresize = W+H; layer = <UIWindowLayer: 0x7199620>>
| <UIView: 0x719ed20; frame = (0 20; 320 548); autoresize = W+H; layer = <CALayer: 0x719edd0>>
| | <UIRoundedRectButton: 0x719b9d0; frame = (51 464; 73 44); opaque = NO; autoresize = TM+BM; layer = <CALayer: 0x719baf0>>
| | | <UIGroupTableViewCellBackground: 0x719c2a0; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x719c370>>
| | | <UIImageView: 0x719da50; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x719dd20>>
| | | <UIButtonLabel: 0x719d0f0; frame = (12 12; 49 19); text = 'Button'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x719d1e0>>
| | <UIView: 0x71a1160; frame = (0 300; 320 88); autoresize = RM+BM; layer = <CALayer: 0x71a11c0>>
| | | <SelectableTag: 0x719fcc0; baseClass = UIScrollView; frame = (20 -112; 62 200); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x71a04e0>; layer = <CALayer: 0x719fef0>; contentOffset: {0, 0}>
| | | | <UIImageView: 0x71a0c20; frame = (55 193; 7 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x71a0cc0>>
| | | | <UIImageView: 0x71a0dd0; frame = (55 62; 7 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x71a0e70>>
| | | | <UIRoundedRectButton: 0x719ddd0; frame = (-1 7; 64 44); opaque = NO; layer = <CALayer: 0x719b630>>
| | | | | <UIGroupTableViewCellBackground: 0x719d630; frame = (0 0; 64 44); userInteractionEnabled = NO; layer = <CALayer: 0x719b690>>
| | | | | <UIImageView: 0x719dea0; frame = (1 1; 62 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x719d990>>
| | | | | <UIButtonLabel: 0x71a1630; frame = (12 12; 40 19); text = 'Test1'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x71a1e50>>
(lldb)
From the documentation of hitTest:withEvent: in the UIView Class Reference:
Points that lie outside the receiver’s bounds are never reported as hits, even if they actually lie within one of the receiver’s subviews. This can occur if the current view’s clipsToBounds property is set to NO and the affected subview extends beyond the view’s bounds.
The parent of your scroll view is the view with address 0x71a1160. Notice that the scroll view's frame.origin.y is -112. So the top 112 points of the scroll view are outside of its parent's bounds. That part of the scroll view will never receive touches. Your Test1 button is entirely in that part of the scroll view.
I have noticed this behavior too with UIButtons. After changing the frame of the parent view, if you add the button again it will work.

addSubview change the index of one object in scroll.subviews

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.

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)]) {
}

Resources