I'm creating a registration form application. Users of the application will be able to add and delete questions.
So basically I have a class called questions and the methods for "modifying" questions will go under it. Right now I am working on the methods for adding a question to the form.
A question will consist of:
UILabel (What is your name?)
UITextField or UISegmentedControl
(Used for multiple choice question)
I am very new to Swift and still what I would consider a beginner at object-oriented programming. Right now I am trying to design the Questions class layout, should it look something like this?
class Question {
var label: UILabel
var multiChoice: UISegmentedControl
var textInput: UITextField
init(label: UILabel, multiChoice: UISegmentedControl, textInput: UITextField) {
self.label = label
self.multiChoice = multiChoice
self.textInput = textInput
}
// methods for adding question
}
So obviously the composition of a question will depend on actions (buttons pushed) the user takes. When a user selects to add a new question they will input a label, and decide whether they want to use a segmented control or text field.
Here's where my question comes in. After the user has decided on the parameters, my method for adding a question should create a new instance of a Question, which will be returned. This new instance of a Question should then be added to an array that stores all the created questions. Would this array be initialized in the action (pressing the add question button) or should it be initialized globally, so all future methods I add can access it.
The fewer global variables, the better.
Given the class above, I would expect your method for creating a Question will be a method of some UIViewController subclass and the array containing all the Questions should be a property of that same view controller sub-class.
The method that creates questions will have to add the label, segmentedControl and textInputs to some UIView (possibly the view controller's main view) so they can be visible.
Another quick note... If a Question can be either text input or multiple choice, but not both, then this one class should not have both fields in it. You will need two Question sub-classes (FillInQuestion and MultiChoiceQuestion perhaps,) possibly both derived from a Question base class.
Related
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() {
...
}
}
I am working with keyboard resign features in iPhone app development. I would like to know why
self.textField.delegate = self
needs to be included into the viewDidLoad of a viewController. I have tried to find reasons of this but no explanation has been clear so far.
A few points
The reason you need to set the delegate is because without it the view doesn't know about the view controller. So it wouldn't know about your method textFieldDidEndEditing and it would never be called.
That is the basic premise of delegate, you are telling that object, "here is an object that I want you to call methods on"
It doesn't have to be set in viewDidLoad - but it's often the most convient place to set up delegates for views.
The delegate doesn't have to be the view controller (self), in your case it's the simplest way, but with a UITableView its common to have another class be the delegate so that all the logic isn't in one place and so it can be changed.
The UITextFieldDelegate protocol defines methods that you use to manage the editing and validation of text in a UITextField object. All of the methods of this protocol are optional.
A text field calls the methods of its delegate in response to important changes. You use these methods to validate text that was typed by the user, to respond to specific interactions with the keyboard, and to control the overall editing process. Editing begins shortly before the text field becomes the first responder and displays the keyboard (or its assigned input view).
From more info. check apple doc.
Its not necessary to use self.textField.delegate = self if you don't want to manage the editing and validation of text in a UITextField object as all the methods of UITextFieldDelegate is optional.
For your other questions like what does .delegate = self do??
When you "set the delegate," what you are doing is saying where you want the messages to go.
Hence,
blah.delegate = amazingPlace will send the messages to "amazingPlace".
blah.delegate = somewhereElse will send the messages to "somewhereElse".
blah.delegate = self will send the messages to you.
... check this source link for details
Delegates are key concepts in iOS development so I'd suggest taking a good look at the documentation for them. It can be particularly useful to create your own custom delegates in certain situations too so understanding and using them in the right places can really help improve the structure of your projects.
There are a couple of key reasons for using them. Firstly, they allow safe communication between classes. In your example, the textField object that you're using is communicating back to your view controller. This is why you need to set your view controller as its delegate. Otherwise the text field doesn't have a delegate object (your view controller) to communicate with. The text field fires certain methods at certain times, such as textFieldDidBeginEditing, and calls these on its delegate object if it has one. When you register your view controller as the text view's delegate you can tap into these callbacks.
The other benefit is that delegates allow you to separate concerns and encapsulate or abstract responsibilities. It might be that the main concern for the text view is how to handle text in its view but not necessarily what to do when has been entered, or when the return button in the keyboard is pressed, or how to validate text that has been input. It's better that these tasks are handed over to something else, such as a delegate (in Obj-C parlance), and that is why in your example you have to register one class as the delegate for another.
As stated before, UITextfield delegation allows you to control events on your textfield.
You ll have the ability to edit functions like
textFieldShoulEndEditing
or
textFieldDidEndEditing
in order to add custom rules, for example : text validation.
Take a look at Apple doc.
If you don't need it, you can delete this line and UITextfieldDelegate on your class declaration.
You need to either set the delegate of a UITextField in code with self.textField.delegate = self
or make your viewcontroller (or any other class) a delegate with class MyViewController: UITextFieldDelegate and set the delegate of the UITextField in the storyboard by control dragging from the textfield to the viewController.
I am newbie in iOS with swift. What I need to do right now is that I have a textfield for user to enter his/er username. And once he clicks the other textfields, say password section, the application will automatically check whether this name exists or not and display a "V" or "X" image in a imageView. But I don't know how to do that or what method or action I should deal with. In Android, I could detect the focus of that textfield.Once the textfield loses the focus and if the text isn't empty, I can retrieve the text and request to my server to verify whether it exists or not. In iOS, I'm totally confused how to detect this, and is this related with first responder? Thx for advice in advance!
Use UITextFieldDelegates.
class XXX : YOURCONTROLLER, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.PASSCODE.delegate = self
}
func textFieldDidEndEditing(textField: UITextField) {
if textField == PASSCODE {
//update stuffs
}
}
}
On iOS, you generally create the interface in Interface Builder (a graphical tool you can use to place UI elements on screen and define many of their properties), and then you link them to your code using what's called IBOutlets/IBActions.
The code your link those elements to is often the view controller ; the view controller is the object that is responsible for managing a view and the events it receives.
To make an IBOutlet, go to your interface builder file (1), select the view controller you are interested by (2, for you it will be the one it which your form is present) open the assistant editor (3), the assistant editor should show to code corresponding to your view controller. Then control drag to the inside of your view controller class definition (4).
Once you do that there will be a little "popup" asking you wether you want an outlet or an action (5), if you just want a reference to the given UI object, then select an outlet.
If the object does an action (for example a button) and you want a method to be called when this action occurs, then you would choose action.
From there this should be pretty straightforward, what I would do would be to make an outlet to the textfield containing the password, and an action for the "Send/Connect" button, whether the method linked to this event would be called, I would check if the password is right or wrong.
EDIT : Maybe I added to much details and you already know a lot about what I told you, but when beginning, those things aren't always that much easy.
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.
note: This is an expansion (and clarification) of a question I asked yesterday.
I am conducting a research project where I want to record all of the user's touches in the iPhone app. After the experiment, I will be able to download the data and process it in either Excel or (more likely) Matlab and determine how many times they clicked on certain buttons, when they clicked certain buttons, etc. To do this, I would need to know:
a) When they touched
b) Where they touched
c) Which view they touched
The first two are easy, but the third I am having trouble with. I know I can do this to get the reference to the UIView that was touched:
CGPoint locationPoint = [[touches anyObject] locationInView:self];
UIView* viewYouWishToObtain = [self hitTest:locationPoint withEvent:event];
However, that will just give me a pointer to the view, not the name of the view that was touched. I could assign each view a tag, but then every time I create a new view I would need to remember to tag it (or, alternatively, log the address of each view when initialized and log it when the view is touched). Subclassing UIView and adding an automatic tag isn't really an option since I'm creating other UIButtons and UISliders and would need to subclass those also, which doesn't seem like a very good solution.
Does anyone know of a clean, easy way to do this?
For "Which view they touched", what information do you need?
Perhaps you could use a category to add a method to UIView. This method would generate a string containing information about the view. Such as:
its type e.g. UIButton etc.
its size and position
the title of the view, if it has one (e.g. the button title)
the parent view type and title
other stuff e.g. is the view enabled, what state it is in. anything you like.
For example: "Type:UIButton Title:"Back" Rect:{3,5,40,25}" or some such string.
This is very clean and gives you quite a lot of information to be going with.
You could add a category to UIView which would then be inherited by all UIView descended objects, although I'm not sure its any more efficient than tagging. Since a category can override methods then you could override init methods for automatic tagging I suppose.
http://macdevelopertips.com/objective-c/objective-c-categories.html
I'm not sure what you mean by the "name" of the view. If you mean the view name in Interface Builder, I don't believe it includes that in the instantiated objects. You could use the Tag attribute which is included, but that's just a number and not a name.