IBOutlet not connecting in SWIFT - ios

All,
I have this in swift
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
So if i go in the storyboard, I should be able to see that, and I should be able to connect it like this :
So I should be able to go to 'New Referencing Outlet' and drag it on the view controller (yellow tab at the top) and I should see 'tableView' and connect it. This doesn't happen , I am confused why !

Do no type following line in advance.
#IBOutlet var tableView: UITableView! // <-- this line
Instead, add a UIComponent in your storyboard first and then using "assistant editor" drag the connection link in your swift file.

On the picture you posted I can see you are looking for IBOutlet, but you selected the tableView not the whole controller.
Click on the white status bar (where yellow - controller and 2 oranges - responder and exit buttons are) then you will see your IBOutlet

Related

Where should I drag and drop "label"?

Now I'm learning swift using Xcode, but I don't know where to drag and drop and why drag and drop "label" to somewhere
should I drop no.1? or no.2? or no.3? and why I should drop there?
If you drop it to 1, Xcode automatically generate an #IBOutlet for you. If you drop it to 2 or 3, then #IBAction. There's no other reason for that except that Xcode tries to be smart and help you organize code more nicely: properties with properties in the top of the class, methods – in the methods area. And you can also move declarations to another place later: except for code style matters, it doesn't matter, where exactly within your class you put declarations.
as you are trying to take an IBOutlet for a label , its nice to keep it on top of the class (where you mention 1).
normally Xcode gives suggestion you , if you drug on top side it will be #IBOutlet
or you on bottom like 2 or 3 it will be #IBAction like you already took a button action in your code .
Your Solution On Code:
import UIKit
class CodePresentViewController: UIViewController {
#IBOutlet weak var YourLabel: UILabel! // insert #IBOutlet type property here
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func tapBackButton(_ sender: UIButton) {
//Yout Button COde
}
}
If you want to own the label in your code, and then make some configuration to the label by code, use "1". It will give you a #IBOutlet label object in your code.
If you want to set the label's action, use "2" or "3".

Xcode Error: Outlets cannot be connected to repeating content

After doing some searching and editing, I can't seem to find a solution to fixing this error. I'm trying to link my location search results with a table to display the search results in a list-form.
I have my map with the details button linked with a UIViewController called 'FirstViewController.' My results table is linked with a UITableViewController called 'ResultsTableViewController.' My prototype cells are linked with a UITableViewCell called 'ResultsTableCell' which is also where my outlets are located.
Here are the 2 separate errors:
Illegal Configuration: The nameLabel outlet from the ResultsTableViewController to the UILabel is invalid. Outlets cannot be connected to repeating content.
Illegal Configuration: The phoneLabel outlet from the ResultsTableViewController to the UILabel is invalid. Outlets cannot be connected to repeating content.
I've read other people's posts with the same problem, tried to fix them accordingly and I'm still getting the same error.
Here is the code for populating the cell, located in my ResultsTableViewController.
let cell = tableView.dequeueReusableCellWithIdentifier("resultCell", forIndexPath: indexPath) as! ResultsTableCell
// Configure the cell...
let row = indexPath.row
let item = mapItems[row]
cell.nameLabel.text = item.name
cell.phoneLabel.text = item.phoneNumber
return cell
}
The code in my ResultsTableCell class:
import UIKit
class ResultsTableCell: UITableViewCell {
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var phoneLabel: UILabel!
}
This message only occurs if you connect it to the view controller. As I have already commented, you probably did not delete the first connection outlet you've made to your view controller. Even if you delete the IBOutlet code from your view controller you still need to right click it and delete the old connection that probably still there. After deleting it the error message will go away.
this issue happen when you delete view from your class but still have reference in your view
here is example I remove back outlet reference from my class but my view still keep the reference Notice yellow rectangle just delete it by click at x
if you want to know how to reach this view , open your storyboard , right click at top left yellow it will show this dialog

How to make the keyboard go away

I have seen other threads answering this question but my issue is I don't understand what is being said, being new to programming. My app has a User ID and Password text field to let the user log in with current credentials. When they data is entered, I want the user to be able to make the keyboard go away.
Here is what I have done. The problem is, nothing happens. Or, I don't understand what I have written and am not testing it correctly (although I am testing it as I would expect my novice users to, and it is not acting as expected). I appreciate any help you can give.
These text fields and this button are defined in the class ViewController: UIViewController. Then the function to hide the keyboard is in the ViewDidLoad method.
#IBOutlet var loginEntered: UITextField!
#IBOutlet var passwordEntered: UITextField!
#IBAction func loginButtonTapped(sender: AnyObject) {
override func viewDidLoad() {
super.viewDidLoad()
self.logInError = 1
func textFieldShouldReturn(passwordEntered: UITextField!) -> Bool {
passwordEntered.resignFirstResponder()
return true
}
Thank you again,
Greg
This is the step by step approach of your problem. I will show you mostly with storyboard.
Step 1: Go to the Project Navigator on left and select Main.stoyboard and select the ViewController in which you want to add your textfields and button.
and then add the 2 UITextfields and one UIButton by dragging and dropping from the object library in your ViewController in storyboard.
Step 2: Add your IBOutlets for the textfields and button in your ViewController-
Spet 3: Go back to your storyboard, select the view controller and click on the right most icon which is called the connection inspector. There you will see the your textfields and button names under the Outlet.
Now connect them by clicking and holding the outlet from the inspector and drag from there to the desired textfield or button. Do that for all. If you miss any connection then your code has no way to determine which variable corresponds to which component(TextFields or Button).
Step 4: Select your TextField, userID from the storyboard, then in the Connection inspector, you will see an Outlet called "delegate"(see the image below). It is this specific textfield's(userID) delegate which you need to assign to your ViewController. This tells your Textfield that, the View Controller will implement its delegate methods.
Do the same for the "password" TextField too. After you connect the password textField's delegate to the view controller, it will look something like this -
Now you are good to go.
Step 5:
Finally, go to your View Controller and add the "func textFieldShouldReturn(textField: UITextField!) -> Bool" delegate method.
This is the complete solution which I tested in my device too. Hope I have made it clear..
simply there are two steps you need to do
The class should conform to UITextFieldDelegate protocol by declaring beside the inherited superclass of what you use , UITextFieldDelegate so for example if your class inherits from UIViewController it will be like that
class ViewController: UIViewController , UITextFieldDelegate
since the class now conforms to the UITextFieldDelegate protocol put this delegate method somewhere in the class optional func textFieldShouldReturn(_ textField: UITextField) -> Bool
and return YES
Hey check the apple developer guide for it here
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextFieldDelegate_Protocol/#//apple_ref/occ/intfm/UITextFieldDelegate/textFieldShouldReturn:

Renaming an outlet in Swift

I accidentally misspelled one of the outlet's in my view controller and ran into a few issues. When I manually try to correct the typo I get stopped at runtime within AppDelegate I'm shown the message,
Thread 1: signal SIGABRT
which highlights the beginning of the code block:
class AppDelegate: UIResponder, UIApplicationDelegate {
...
}
I've found that to fix this issue in Objective-C you would right-click the outlet's original name and "Refactor => Rename" but unfortunately I get the message:
Xcode can only refactor C and Objective-C code
View Controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var billTextField: UITextField!
#IBOutlet weak var tipRateSegmentedControl: UISegmentedControl!
#IBOutlet weak var tiLabel: UILabel! // Variable name should be "tipLabel"
#IBAction func calculateTapped(sender: AnyObject) {
var userInput = billTextField.text as NSString
var totalBill: Float = userInput.floatValue
var index: Int = tipRateSegmentedControl.selectedSegmentIndex
var tipRate: Float = 0.15
if index == 0 {
tipRate == 0.15
} else if index == 1 {
tipRate = 0.20
} else {
tipRate = 0.25
}
var tip: Float = totalBill * tipRate
tipLabel.text = "$\(tip)"
}
}
EDIT: Since Xcode9, there's a refactor function; the new good method is the one in this answer
Since Xcode 6, you can look for your outlet names directly in the Find navigator (Cmd+3), it shows occurrences in your code and in your xibs and storyboards. It also works with actions.
Just search the name in the Find navigator.
You can see that the second result is a reference in a storyboard. You can replace one by one by clicking on each result and press Replace, or you can directly Replace All if you are sure you don't break anything.
Refactor > Rename...
Xcode 9 had many editor improvements including a feature that changes an outlet/action name in the code and storyboard from one place.
In the example Swift code below, right click on btnRequestCode, from the popup menu select "Refactor > Rename...", change the outlet/action name and Xcode changes it in the Storyboard also.
#IBOutlet weak var btnRequestCode: UIButton!
With swift this kind of refactor doesn't work yet. You have to change the name of the outlet, and then delete and reset the connection in the interface builder.
Updated:
Right click the IBOutlet that you want to rename, delete reference outlet, and then reassign it, but you don't have to do anything with your code.
I like to fix situations like this by just opening the Storyboard as source code and editing the XML-like tags.
Right click the .storyboard file and choose "Open As". Search for the old outlet (or action/method) name that is still set in the storyboard but which no longer matches the renamed method/outlet object in the View Controller. Edit the Xml tag in the storyboard to give it the new name of your outlet or action in the view controller.

Swift put multiple IBOutlets in an Array

I made these (marked with red border) IBOutlets using ctrl + drag
But i don't like to have the exact same line 9 times (DRY)
How do i put these IBOutlets in an Array?
you can define a generic outlet collection in Swift like this:
#IBOutlet var collectionOfViews: Array<UIView>? // = [UIView]?
or for e.g. UIButton objects:
#IBOutlet var collectionOfButtons: Array<UIButton>? // = [UIButton]?
you can find your collections under the Outlet Collections group as usually are in the File's Owner:
it would look on my console after connecting 5 random buttons:
Follow these steps to create an array of outlets an connect it with IB Elements:
Create an array of IBOutlets
Add multiple UIElements (Views) in your Storyboard ViewController interface
Select ViewController (In storyboard) and open connection inspector
There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
Connect if with your interface elements
-
class ViewController2: UIViewController {
#IBOutlet var collection:[UIView]!
override func viewDidLoad() {
super.viewDidLoad()
}
}
Solution here Swift - IBOutletCollection equivalent
#IBOutlet var objectCollection: [Object]
This is for macOS (should be similar for iOS) and I do not find an "Outlet Collections" in my storyboard (looks like they took that option out). So I put all my buttons in an NSStackView and linked the stack from storyboard
#IBOutlet weak var buttons: NSStackView!
and then I looped over them to make changes accordingly
for case let (index, button as NSButton) in buttons.arrangedSubviews.enumerated() {
if(index + 1 != someButtonIndex) {button.state = .off}
else {button.state = .on}
}
you can also use tag instead of index
Start with the two view pane where you see both your code and the storyboard. When you make your first IBOutlet connection from the UI to your code, just look carefully at the Connection drop down field and select the option called "Outlet Collection". This will automatically create an array of IBOutlets. Next just look for the little black circle within a circle that is placed in your code where the array is created. Just drag from this circle to all the other UI objects you want to connect to that same collection (not sure if you can mix types). Similarly you can connect all the objects to one Action by dragging from the first black dot created to all the other objects you want to wire up to that action. Also consider EnumerateSequence() to help in working with this Collection. Sweet right?

Resources