How to get subviews of UIButtonBarStackView? - ios

I am trying to get the subviews of UIButtonBarStackView, so that I can find the right bar button and disable it. I am trying to hide share button in QLPreviewController with usdz files. I have subclassed QLPreviewController and I have this code in viewDidAppear. I can get the subviews till this point and these subviews of StackView returns empty array. Here is my code -
UINavigationController *navController = self.childViewControllers.firstObject;
for(UIView *toolbar in navController.view.subviews[2].subviews) {
if ([NSStringFromClass([toolbar class]) containsString:#"ContentView"]){
for(UIView * stackView in toolbar.subviews) {
if ([stackView isKindOfClass:[UIStackView class]]) {
//StackView subview is empty.
}
}
}
}
Any help is much appreciated. Thanks!

Related

UIButton not working in UITableview

Have UITableviewcell --> inside which i have 4 different UIView and 3 of the views has UIButtons. I want to make UIButton clickable. For the first time the buttons are clickable but when i go to next screen and come back, the buttons don't work. Please let me know how to implement this? Thanks!
PHMyTripView *tripsView=[[PHMyTripView alloc] initWithFrame:CGRectMake(10, 5, self.frame.size.width-20, cell.frame.size.height)];
tripsView.onBaggageClick = ^{
[weakSelf handleBaggagePurchaseTapped];
};
if ([data count]>0) {
[tripsView fillTripData:[data firstObject]];
[tripsView showAncillaries:self.predictiveManager.upcomingCDAirBookingInfo];
}
[cell bringSubviewToFront:tripsView.bagsButton];
[cell.viewPlaceHolder addSubview:tripsView];
This happens because the cells are reusable and if you go to another screen the button may kinda mess round into different cell in UI or functionally.
The way to solve this is to add tag. You can define cell.tag = indexPath.row * 10 or so.
Then when draw the button, you check the condition, if cell.tag == ?, then add your button.
Thank you everyone for your response but they din't work in my case.
Here is the answer. Since the UITableview was reloading when it comes back to the screen.The frames were mis placed and Hence the button was not able to click.
Used this one line code which worked fine.
self.tripsView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
You should turn off delaysContentTouches on each UITableView subview, which is an instance of UIScrollView class.
Subclass UITableView and override initWithFrame method:
.h file
#interface NoDelaysOnTouchTableView : UITableView
#end
And .m file
#import "NoDelaysOnTouchTableView.h"
#implementation NoDelaysOnTouchTableView
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame: frame];
if (self) {
for (id view in self.subviews) {
if ([NSStringFromClass([view class]) isEqualToString: #"UITableViewWrapperView"]) {
if ([view isKindOfClass: [UIScrollView class]]) {
// turn OFF delaysContentTouches in the hidden subview
UIScrollView* scroll = (UIScrollView*)view;
scroll.delaysContentTouches = NO;
}
break;
}
}
}
return self;
}
#end
Next - use this subclass (create an instance of NoDelaysOnTouchTableView) to be able to press UIButton immediately.
I think that the causes would be multiples.
You can try:
check the constraints for each button in your cell
in cellForRow you can do addTarget: for each button with relative #selector and in this method check the object (datasource) associated to button.
do not use addSubView in your cell, instead use a Xib (or define your cell in a storyboard within tableView) so you can set the constraints.
I Hope, i've helped you.
Not specifically about this issue, but for some people it may be the case.Try to add subviews in contentView of the cell.
Instead of addSubview(textField) use contentView.addSubview(textField)

UISearchBar on UITableView with scope bar resizes itself over other UI items

Ok, so I've got a UITableView below a UISearchBar. Above that is just some UILables and UIButtons and then the UINavigationBar.
The UISearchBar has the scope bar enabled. Whenever I tap on the search bar I get the following odd behaviour (I've got the on screen keyboard disabled but the focus is in the UISearchBar text field):
Where as normally it looks like this:
It's really frustrating and I can't work out why it's happening. Has anybody experienced anything similar and found a solution?
Thanks!
It's a bodge, but it's the best I could come up with. I just put the following in viewWillAppear and then manually created a background image of 44px high and put it behind the UISearchBar on the storyboard.
-(void)viewWillAppear:(BOOL)animated
{
[self.searchBar sizeToFit];
for (UIView *subview in self.view.subviews) {
for(UIView *subView2 in subview.subviews){
for(UIView *subView3 in subView2.subviews){
if ([[[subView3 class] description] isEqualToString:#"UISearchBarBackground"]) {
[subView3 removeFromSuperview];
break;
}
}
}
}
}

Remove view of particular class from window

Is there anyway to remove a view from the uiapplication window of a particular class?
I have a class called MainView that is the top header bar for the app on the main screen. I have a view that gets added after that where users can swipe up and down to different screens but on the screen where a user swipes up or down too the MainView bar at the top needs to be removed. How should I go about this? Should I try removing this MainView class from the UIApplication?
[yourSubview removeFromSuperview];
If your MainView instance is added directly to the window, you can get the array of the window's subviews. Then iterate over the subviews until you find a view that is type MainView and remove it from the window.
NSArray *subviews = [UIApplication sharedApplication].delegate.window.subviews;
for (UIView *view in subviews)
{
if ([view isKindOfClass:[MainView class]])
{
[view removeFromSuperview];
break;
}
}

Scroll to top with status bar tap

I've looked through various SO questions on the topic and I have not found a solution. I have a UIViewController with a UITableView and a UICollectionView. I want the UICollectionView to scroll to the top, when the user taps it.
The documents say if you have more than one UiScrollView subclass - you need to set them to no and the UiScrollView you want to scroll to the top, to yes.
So I wrote this bit of code to go through all my views:
for (UIScrollView *view in self.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.scrollsToTop = NO;
}
}
self.collectionView.scrollsToTop = YES;
This way I am sure any subclass of UiScrollView has it's scrollsToTop property set to no.
However tapping on the status bar does not do anything.
Can someone tell me what I am missing here?
Thank you
It seems that you are only iterating through the subviews of your main view. Your UITableView may be nested inside another view. Try doing the following;
//in view did load
[self setScrollToTopFalse:self.view];
self.collectionView.scrollsToTop = YES;
-(void)setScrollToTopFalse:(UIView *)v
{
for (UIView * v1 in [v subviews]) {
if ([[v1 class]isSubclassOfClass:[UIScrollView class]]) {
((UIScrollView *)v1).scrollsToTop = NO;
}
[self setScrollToTopFalse:v1];
}
}

iOS: setting Exclusive Touch to all buttons in a view

My app has many buttons in a Window and I want to set Exclusive Touch all of them together. Do you have any suggestion about this? Thanks
There is a way to set exclusive touch to all buttons in your app, may be helpful.
#import </usr/include/objc/objc-class.h>
static IMP gOringinalWillMoveToSuperview = nil;
static id newMoveToSuperviewPlusSettingExclusiveTouch(id self,SEL selector,...)
{
va_list arg_list;
va_start( arg_list,selector);
gOringinalWillMoveToSuperview(self,selector,arg_list);
[self setExclusiveTouch:YES];
return nil;
}
-(void)addSettingExclusiveTouchToAllUIViewMethodWillMoveToSuperview
{
gOringinalWillMoveToSuperview = class_getMethodImplementation([UIButton class], #selector(willMoveToSuperview:));
class_replaceMethod([UIButton class], #selector(willMoveToSuperview:), &newMoveToSuperviewPlusSettingExclusiveTouch, "v#:");
}
if you don't understand this, you can refer to this and this.
Are you just looking for an easy way to set them all at once?
If you have all the buttons in an array (e.g. they're all connected to the same IBOutletCollection) you can use key value coding to set the exclusiveTouch property of the array:
[buttonArray setValue:[NSNumber numberWithBool:YES] forKey:#"exclusiveTouch"];
NSArray will then invoke the same method on every item in the array.
-(void)setExclusiveTouchForButtons:(UIView *)myView
{
for (UIView * v in [myView subviews]) {
if([v isKindOfClass:[UIButton class]])
[((UIButton *)v) setExclusiveTouch:YES];
else if ([v isKindOfClass:[UIView class]]){
[self setExclusiveTouchForButtons:v];
}
}
}
then call this function at viewDidAppear
If these buttons are all in the same view, you can loop through the view's subviews, test for whether the particular subview is a button (or test for a tag if you have one set) and set exclusiveTouch on each.
I just found an answer for this:
#pragma mark Set Buttons Exclusive Touch Yes
-(void)setExclusiveTouchForButtons:(UIView *)myView
{
for (UIView * button in [myView subviews]) {
if([button isKindOfClass:[UIButton class]])
[((UIButton *)button) setExclusiveTouch:YES];
}
}
Source
If you want to set exclusiveTouch for ALL UIButtons in your whole application method swizzling will be the perfect solution for you.
This answer explains the way very well : https://stackoverflow.com/a/24534814/976246 , and it works perfectly for me.
Also go through this article to know how this (http://nshipster.com/method-swizzling/) tecknique can be used for various purposes.
If you are adding buttons pragmatically, then send a message to the button [button setExclusiveTouch:YES]; for each buttons before adding to its super view. Else if you are using xib, you have to send the same message to the button in viewDidLoad or in loadView.
Here is some code in swift that will set exclusive touch to all buttons in your viewcontroller's view
for button in self.view.subviews {
if(button.isKindOfClass(UIButton)){
(button as! UIButton).exclusiveTouch = true
}
}
Even though the question was asked many years ago, here is a simple way to set isExclusiveTouch for all subviews that are buttons. This example shows code for subviews of self.view. Change self.view to your view of interest.
Seems like cleaner code for anyone with questions on this in the present.
for subview in self.view.subviews
{
if subview is UIButton {
subview.isExclusiveTouch = true
}
}

Resources