Create a dynamic sequence of pages in swift ios - ios

I am writing an iOS app using swift. The app is a Tour and takes the user through a series of steps.
Each step has generic properties like so:
class Step
{
var name : String;
var description : String;
}
The step will be displayed in the same way, with Name at the top and a "Next" button at the bottom which moves onto the next step. The standard UI back button will be available at the top as usual.
But, I also want to make certain steps perform certain functions, like:
show a video
show a map
take a picture
I'd like to consolidate each of these step types in to a reusable view or controller.
My question is, what is the best way to structure this in terms of Controllers and Views?
I'm currently using a StepViewController : UIViewController with a single View.
When I click NEXT, it creates a new instance of StepViewController, passes it the next step object and adds it to the stack using instantiateViewControllerWithIdentifier.
Which is the better method...
Create a new super-class ViewController of StepViewController for each Step Type, e.g. VideoStepViewController : StepViewController?
Create a new View for each Step Type, allowing the master StepViewController to dynamically load a particular View (e.g. VideoView) into the master controller.

Related

Duplicate Button actions on different View Controllers?

I have a button on one of my view controllers which controls a score action (counter).
Can someone help me duplicating the button and the action it takes and place the duplicate on a separate ViewController?
I need this for a workout Application i'm making and I want to get the action Proof of concept complete before I implement it into my App.
I have attached my Xcode Project with the stage I am now on.
Ive tried passing the name of the action button from the main VC to the newest but I've had no luck.
https://github.com/Mulreany93/NewVCActionButton
I saw in your GitHub that you have an empty class called ViewControllerNewButton, which inherits from UIViewController. I suggest making your scorebutton into a new class called something like e.g. ScoreButton, which should inherit directly from UIButton - class ScoreButton: UIButton {...} Then in each View Controller you can create your scorebutton: let scoreButtonTest = ScoreButton() and then you can use e.g. conversion functions like scoreButtonTest.someConversion() from your ScoreButton class.
If I am on the wrong track, feel free to comment but as far as I can tell you are just trying to use your button in multiple VCs and that's a good place to try inheritance.
Edit for clarification:
class ScoreButton: UIButton {
func someConversion() {
...
}
}

Wanting to use a UIViewController flow for two separate cases

I have two UIViewControllers - one that handles the camera, and the other that allows the taken picture/video to be edited. These two go hand-in-hand to form part of a picture-taking flow within my app. I want to use these two controllers in two different circumstances:
The first is that after the image has been edited, it's passed to another UIViewController to add some additional info to the image.
The second is that after the image has been edited, it should return that image to the UIViewController that initiated the camera view flow.
How should I be telling my UIViewController flow which UIViewController to send the edited image to? Do I need to pass an enum variable along the flow or is there a better way?
I think add a complete handler to the UIViewController is a good way. You may send the complete closure to your UIViewController. Enum is good too.

How to replace content ViewController inside other View controller

I am working on an application which allows users to work with a couple of workmodes. Main view of the app contains information common to all workmodes. I want to create a "subview" with ability to change its ViewController. This subview will be used to display information connected with specified workmode. It is important that app goes to MainViewController from WorkmodesViewController in which user chooses workmode to work with.
My question is:
Which tehnique should I use to acheave changeable WorkmodeViewController inside MainViewVontroller
I have found example git project with functionality I need:
https://github.com/mluton/EmbeddedSwapping

Array of UITextView's that interact with objects of the other classes

I'm rather new to objective C and at the moment I'm trying to create one small project.
The task I want to accomplish is the following:
I've got the UIViewController for the screen of the game I'm creating. It has an UIImageView and a UITextView on it. What it does so far is that the latter one is moving towards the former one. And when their frames intersect (CGRectIntersectsRect) some actions happen.
What I want to achieve next is to create a specific class for UITextviews, so that there will be many of them created on the screen of UIViewController (I think array should be used here). And next I want every of them to be checking themselves, if they have an intersection with the UIImageView - than (again) something happens.
I've tried several ways like creating a mutable array, but every time I've some errors connected with variables of the original ViewController used inside of the new class (Hit).
The code I use for the one existing UITextView, that is created inside of UIViewController, is the following:
-(void)Moving{
HitR.center = CGPointMake(HitR.center.x+HitRX, HitR.center.y+HitRY);
if (CGRectIntersectsRect(HitR.frame, Finish.frame)) {
/*some actions here*/
}
}
etc
Can you help me to create these array of UItextFields, using their own class, tell them what to do with the help of properties like UIimageview.frame from the ViewController and then to place them on the screen.
P.S. I've read numerous articles about how to transfer variables from one class to another, but still failed to accomplish my aim.

I'm having trouble dynamically updating a UILabel in one controller from another. It needs to correspond to a checkbox being checked in objective-c

Working on a shopping store app. I've been going in circles for the past week and a half trying to figure out how to correctly do this. The problem lies in a UILabel that needs to be dynamically updated with text that corresponds to checked checkboxes. It also needs to know whether to apply selection when apply button has been tapped or return previous selection if customer decided to change their mind and not tap apply. This is where I'm running into issue.
I refer to 3 controllers as image 1, image 2 and image 3.
My model is a separate class that I pass copies of back and forth to keep selections made by users when they wish to refine a collection of clothing item results.
So for example the user taps the refine button in image 1
They are taken to image 2 where they decide what they want to refine results by
They are then taken to image 3 page where they make the selection
Where problems begin:
In short in image 3 a customer makes a selection and taps done, they are then taken back to image two where their selection is shown in a string separated by commas in a UILabel underneath the chosen refine by option e.g. Gender. If they are ok with their selection they tap apply and the refining is done and displayed like in image 1. A tick is also shown in the refine button to make the customer aware refining is active.
Now lets say a selection has already been made like in the images below and the customer goes back to image 3 to modify a selection. Let's say he unchecked "microsites". What should happen is when he goes back to image 2 the list underneath the refine by option should be updated.
This works fine but I'm actually updating the property that is updated when the apply button is tapped. So if the customer decides they don't want to refine anymore and don't click apply but the back button instead to take them to image 1 then I need the original selection string to be updated in the property.
The thing is this very property is updated whenever a selection is made in image 3. So when the customer does return to image 2 then because we unchecked "microsites" only "men" will show in the string underneath the refine by option.
I've tried creating a temp property to hold the previous selection but thing's just really get messy with all this going back and forth.
Further info:
I pass my model class back and forth between controllers using the prepareForSegue method and delegation/protocols.
Image 2 is aware when the done button in image 3 is tapped. This is where I pass the model over. Image 1 knows when the apply button in image 2 is tapped and again this is where I pass the model over. To pass the model from image 1 to 2 then 2 to 3 I use the prepareForSegue method.
Image 1:
Image 2:
Image 3:
How would you do this? I feel I've made a good start by moving all my model into its own class. This has made things easier but the other problem with the UILabel is holding me back.
Update:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[[sender titleLabel] text] isEqualToString:#"Gender"]) {
VAGRefineGenderViewController *vc = [segue destinationViewController];
[vc setDelegate:self];
[vc setRefineModel:[self refineModel]];
}
}
Working code:
#implementation VAGRefineModel
{
VAGRefineModel *_object;
}
-(id)copyWithZone:(NSZone *)zone
{
VAGRefineModel *modelCopy = [[VAGRefineModel alloc] init];
modelCopy->_object = [_object copyWithZone: zone];
return modelCopy;
}
Then in image 2/controller 2 I just set the model being passed to controller 3 as the copy of the existing model.
This seems fairly simple.
You should indeed create a copy of the model and pass this to the next viewController then you don't have to worry about the edits made to it.
If the user presses back then that copy is just discarded.
If you press done then you receive the copy and replace your current model then reload your views.
It might look as simple as this (no error handling to make it easy to follow)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
{
Model *model = [self.model copy];
VC2 *viewController = segue.destinationViewController;
viewController.model = model;
viewController.delegate = self;
}
- (void)didTapDoneButtonWithModel:(Model *)model;
{
self.model = model;
[self reloadData];
}
I didn't read your post in detail, but did read enough to get the gist of it.
I'm gonna call your screen level 1 (master), level 2 (top level detail) and level 3 (fine detail) instead of image 1/2/3, because I'm talking about pictures, I'm talking about master/detail view controllers.
It sounds like you have 3 levels of view controllers that allow the user to edit finer levels of detail for a search.
I would suggest setting up your model so you can encapsulate the details handled by levels 2 and 3 into objects. When you get ready to drop to level 3, create a copy of the settings for gender and micro sites, and pass it to the level view controller. The user will interact with level 3, which has it's own copy of the settings.
Level 3 should set up level 2 as it's delegate, with a delegate message
-userChangedSettings: (Level3SettingsObject *) changedSettings
Or something similar.
If the clicks done, the level 3 VC would invoke that method on it's delegate, passing the changes to the Level3Settings object up to level 2, then pop itself/dismiss itself. (whichever is appropriate.)
If instead the user clicks cancel, just close pop/dismiss without calling the delegate method to tell the delegate about the change in settings. The settings in the level 2 object won't have changed.
The same would go for the communication between level 2 back up to level 1.
If it makes sense, you can make it so that the settings for level 1 contain level 2 data objects, and that the settings for level 2 contain level 3 data objects. That way changes to level 3 get passed back to level 2, and if the user cancels from level 2, all the changes made in level 2 and level 3 are discarded, and only if they tap save in level 2 do the changes from that level get passed up to level 1.

Resources