Remove views from StackScrollView - ios

I'm trying to use the StackScrollView class but I feel something important is missing here: we can add views to the stack, but we can't remove them.
Does anyone made a function to do it?
I already tried to add a nil controller but it didn't work?

You remove them using by swiping. If you look at StackScrollViewController.m you'll see there is a bounceBack:finished:context: method which is responsible for animating the view when you go back.
If you want to bounce back programmatically (maybe you have a button for this or anything like that) you should go take a look at how the bounceBack:finished:context: method is used in StackScrollViewController.m

Just add this custom method to StackScrollViewController and then call it from where you want.
- (void)dismissStackViewController {
[[[slideViews subviews] lastObject] removeFromSuperview];
}

Related

How can I detect a subview being added anywhere in the view hierarchy (including subviews)?

I am creating a framework for the other apps to use it. I want to find when the display presented to the user changes. These changes include addition and removal of subviews, scrolling down, adding text, etc. Is there a way I can directly check when the content presented on the screen is changing. Above question is a part of the problem.
Did you mean viewDidLoad?
That function called first time after all view loaded same as ViewTreeObserver.OnGlobalLayoutListener.
After you explanations I would simply do something like this:
class MyViewController:UIScrollViewDelegate{
func addSubview(){
self.takeSnaphot()
}
func scrollViewDidScroll(scrollView:UIScrollView){
self.takeSnaphot()
}
func takeSnaphot(){
//the code to take snaphots
}
}

Check which UIViewController my custom button class is on w/o Storyboard

I have created a custom class for my UIBarButtonItem (refreshIndicator.m). This button will be on many different view controllers, all push-segued from my MainViewController/NavigationController.
Instead of dragging an outlet onto every single ViewController.m file for iPhone storyboard THEN iPad storyboard (ugh, still targeting iOS7), I want to know if there is a way to complete my task simply within my UIBarButtonItem custom class. I've looked around everywhere but I haven't quite found an answer to this,
All I need to do is check which UIViewController is present, check the last time the page was refreshed, and then based on that time, set an image for the UIBarButtonItem. (I've got this part figured out though, unless someone has a better suggestion). How can I check for the current UIViewController within a custom button class? Is this possible?
Does it need to know which view controller its on so it can tell that vc it was pressed? If that's the case, then use your button's inherited target and action properties. On every vc that contains an instance of the button, in view did load:
self.myRefreshIndicator.target = self;
self.myRefreshIndicator.action = #selector(myRefreshIndicatorTapped:);
- (void)myRefreshIndicatorTapped:(id)sender {
// do whatever
}
More generally, its better to have knowledge about the model flow to the views from the vc, and knowledge of user actions flow from the views. Under that principal, your custom button could have a method like:
- (void)timeIntervalSinceLastRefresh:(NSTimeInterval)seconds {
// change how I look based on how many seconds are passed
}
And your vcs:
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:self.lastRefreshDate];
[self.myRefreshIndicator timeIntervalSinceLastRefresh:interval];
If you really must go from a subview to a view controller, you could follow the responder chain as suggested in a few of the answers here (but I would go to great lengths to avoid this sort of thing).
It is possible to achieve this, but the solution is everything but elegant. It is one way of getting around the basic principles of iOS and is strongly discouraged.
One of the ways is to walk through the responder chain, posted by Phil M.
Another way is to look through all subviews of view controllers until you find the button.
Both ways are considered a bad practice and should be avoided.
For your particular case, I would rethink the structure of having a separate instance of the bar button. For example, you could rework it into a single UIButton instance that gets displayed over every view controller and it can also act as a singleton.

Undo Selection with UISegmentedControl

When a user taps on a UISegmentedControl and changes which segment is selected, I want to perform some validation. If the validation fails, I want to 'undo' their selection, and re-select the item that they previously had selected.
What's the easiest way to do this? I think I need something like
- (BOOL) segment:(UISegmentedControl *)seg shouldSelectSegmentAtIndex:(NSInteger)newIndex`
but I was looking at the Apple Docs, but I didn't see anything like that - really I didn't see anything with will in it at all. Will I have to create a category or subclass to do this, or am I just missing it?
I suppose I could add an ivar that holds the selected segment index after it has been validated, and then call [mySegmentedControl setSelectedSegmentIndex:myIvar]; if validation fails, or myIvar = [mySegmentedControl selectedSegmentIndex]; when it passes, but that feels a little messier. It's also a bit of a pain if I have a lot of segmented controls on the same screen. I believe if I do create my own subclass, I'll have to do something like this though.
EDIT:
Other programming languages I've used have natively supported an 'undo' feature, without the programmer having to implement the undo on his own. I'm looking to see if anyone is aware of something like that for Objective-C. If it does not exist, does anyone know of a better way to implement it other than the ivar method I described above?
I don't believe there really is an elegant way to do that without subclassing. But since there are no subclassing notes on UISegmentedControl, that could be an option. Override setSelectedSegmentIndex, where you check through delegation whether that index should be selected. If it should, call super's implementation. If not, just do nothing.
This does assume that there are no internal methods that mess things up (and which you can't override).
Im not exactly sure what you are asking, but if I understand correctly I do believe this would do the trick:
[mySegmentedControl addTarget:self action:#selector(segmentChanged:) forControlEvents:UIControlEventChanged];
- (void)segmentChanged:(id)sender
{
if (myIvar != validated){
[mySegmentedControl setSelectedSegmentIndex:defaultSegment];
}
}

Does willMoveToSuperview will also deallocate the UIView on which its got called?

I was wondering if I can call willMoveToSuperview on UIView and after that retain that view to reuse later for one ? something like following
if (!CGRectIntersectsRect(cell.frame, visibleRegion)) {
[cell willMoveToSuperview:nil];
[self.resuableCells addObject:cell];
}
I am not sure about your intent here...
But WillMoveToSuperview - According to doc:
The default implementation of this method does nothing. Subclasses can override it to perform additional actions whenever the superview changes.
So your code,
[cell willMoveToSuperview:nil];
Has no effect unless you override this method in a cell subclass and implement your own logic there.
Coming to your question -
Does willMoveToSuperview will also deallocate the UIView on which its got called?
Answer is obvious - NO.
willMoveToSuperview is an observer method that the system calls as a courtesy to you in order to give you a chance to handle special cases before it completes some other hidden tasks.
It's default behavior is to do nothing, but you might want to tidy up something in your code prior to a move by overriding this method.
A proper use case might be if you had a view playing a video clip or an animation, and something else in your code is about to rip the view out of it's current hierarchy and place it in some other un-related view hierarchy. You might want the chance to pause the clip or suspend the animation before the move took place.
I doubt it's the right method to handle what you are attempting, and I definitely know you should not be calling it directly.
Feel free to post some more code to show us what you're trying to accomplish and where it's going wrong.

Ideal place to put a method after orientation has changed

I have an issue and here how it goes,
I have a view with a subview, the subview is loaded conditionally, only if the parent view is setHidden property is set to YES;
something like [parentView setHidden:YES] and if([parentView isHidden]),
I want to call a method when the orientation changes and that is the cited snippet above, but I have observed that the method shouldAutorotateToInterfaceOrientation is called 4 times during loading and 2 times during runtime, since the method is called more than once, how can I possibly implement a method call ideally since apple's existing method doesn't seem to give me the intuitiveness to put my custom method call with the existing method.
If I would hack this thing, it is possible, but somebody might have a better idea before resorting to things that in the future would just cause me more trouble than benefit.
TIA
Have you tried with
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
// check here for your desired rotation
}

Resources