I am new to Xcode and have found a useful book online called 'Intro to app development with Swift. It is written for Xcode 10 but I have Xcode 12.4.
The instructions do not follow in the new version. In particular I want to add an image in the View Controller but I can't find anything like Image View in the Attributes Inspector. Can someone indicate. where this is so I can move on from the exercise I am doing.
Also Is there an upto date book online that can help me learn Xcode?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am a begginer using Swift.
In the example I am following from the book ' iOS 14 Programming for Beginners', the instructions tell me to create a folder called Location and as sub folders create 2 other folders called Model and View. It then instructs me to right click on Location, new file (Cocoa Touch Class) and name the swift file LocationViewController and create the file.
According to the book, it should contain the following override function:
override func viewDidLoad() {
super.viewDidLoad()
}
Here is the file that is produced when I create the Cocoa Touch Class, where the above override is missing.
l
//
// LocationViewController.swift
// LetsEat2
//
// Created by Tony Hudson on 17/03/2021.
//
import UIKit
class LocationViewController: UICollectionViewCell {
}
As this is generated by Cocoa Touch, I can't see why this is missing?
Can anybody explain why this code is missing?
I am learning Xcode from Ahmad Sahar's book and somehow I have disconnected the exploreViewController from the navigation controller. I have now progressed far beyond the point where this was connected to the navigation controller, so I Ctrl + Dragged from the button to the navigation controller.
However when I ran the project I get a Compile error:
Couldn't compile connection: IBCocoaTouchOutletConnection: 0x123ef3a50 (sN1-9E-uLq) source=IBProxyObject: 0x123ef2be0 (Wnw-oV-gaS) 'Placeholder for UIStoryboardPopoverPresentationSegueTemplate with OID GlU-yO-pRa' property=anchorView destination=IBUIButton: 0x120195400 (WOO-Ms-Zlt) 'Button'
As I am still learning I am not sure how to fix this problem?
If I click on the segue icon it says 'Present as Popover segue'
and Segue Actions shows 'instantiation' with a circle but if I click on the circle nothing is listed for the segue.
Please help?
I am trying to learn Xcode using iOS 14 Programming for Beginners (Packt Pub).
I have had several problems with the code so I have been ultra careful and I can't find any mistakes.
There is also another error in the code in an extension in the code.
Here is a copy of the code:
/
// MapViewController.swift
// EatOut
//
// Created by Tony Hudson on 15/07/2021.
// Links to: Item -308,318,319,320,321,324,341,352,353
import UIKit
import MapKit
class MapViewController: UIViewController,MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
let manager = MapDataManager()
var selectedRestaurant: RestaurantItem?
override func viewDidLoad() {
super.viewDidLoad()
initialize()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
switch segue.indentifier! { //<<Value of type 'UIStoryboardSegue' has no member 'indentifier'
case Segue.showDetail.rawValue: showRestaurantDetail(segue: segue)
default:
print("Segue not added")
}
}
}
// MARK: Private Extension
private extension MapViewController {
func initialize() {
mapView.delegate = self
manager.fetch {(annotations) in addMap(annotations)}
}
func addMap(_ annotations: [RestaurantItem]) {
mapView.setRegion(manager.currentRegion(latDelta: 0.5, longDelta: 0.5), animated: true)
mapView.addAnnotations(manager.annotations)
}
func showRestaurantDetail (segue: UIStoryboardSegue){
if let viewController = segue.destination as? RestaurantDetailViewController, let restaurant = selectedRestaurant {
viewController.selectedRestaurant = restaurant
}
}
}
// MARK: MKMapViewDelegate
extension MapViewController: MKMapViewDelegate { //<< Redundant conformance of 'MapViewController' to protocol 'MKMapViewDelegate'
func mapView(_ mapView: MKMapView, annotationView view:MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
guard let annotation = mapView.selectedAnnotations.first
else{
return
}
selectedRestaurant = annotation as? RestaurantItem
self.performSegue(withIdentifier: Segue.showDetail.rawValue, sender: self)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation ) -> MKAnnotationView? {
let identifier = "custompin"
guard !annotation.isKind(of: MKUserLocation.self) else {
return nil
}
var annotationView: MKAnnotationView?
if let customAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView = customAnnotationView
annotationView?.annotation = annotation
} else {
let av = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
av.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView = av
}
if let annotationView = annotationView {
annotationView.canShowCallout = true
annotationView.image = UIImage(named: "custom-annotation")
}
return annotationView
}
}
I am wondering if there is some action that I have not done previously that is causing these errors.
Can anyone help?
I am trying to learn Xcode using a book called 'iOS 14
Programming for Beginners'. Although the book is supposed to show the correct
code I have found that it still raises errors when I type in the code. They
also have the code online, which I have downloaded and compared to my code, yet
I still get errors.
Here is the file that produces the errors:
//
// ExploreViewController.swift
// EatOut
//
// Created by Tony Hudson on 15/07/2021
//
import UIKit
class ExploreViewController: UIViewController,
UICollectionViewDelegate {
@IBOutlet weak var collectionView:
UICollectionView!
let manager = ExploreDataManager()
var selectedCity: LocationItem?
var headerView: ExploreHeaderView!
override func viewDidLoad() {
super.viewDidLoad()
initialize()
}
override func prepare(for segue:
UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case
Segue.locationList.rawValue:
showLocationList(segue: segue)
case
Segue.restaurantList.rawValue: //ERROR
HERE
showRestaurantListing(segue: segue)
default:
print("Segue not added")
}
}
override func
shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool
{
if identifier ==
Segue.restaurantList.rawValue { //AND HERE
guard selectedCity!= nil else {
showAlert()
return false
}
return true
}
return true
}
}
// MARK: Private Extension
private extension ExploreViewController {
func initialize() {
manager.fetch()
}
func showLocationList(segue:
UIStoryboardSegue) {
guard let navController =
segue.destination as? UINavigationController, let viewController =
navController.topViewController as? LocationViewController else {
return
}
guard let city = selectedCity
else {
return
}
viewController.selectedCity = city
}
func showRestaurantListing(segue:
UIStoryboardSegue) {
if let viewController =
segue.destination as? RestaurantListViewController, let city = selectedCity,
let index = CollectionView.indexPathsForSelectedItems?.first {
viewController.selectedType = manager.explore(at: index).name
viewController.selectedCity = city
}
}
func showAlert() {
let alertController = UIAlertController(title:
"Location Needed", message: "Please select a location.",
preferredStyle: .alert)
let okAction =
UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(okAction)
present(alertController,
animated: true, completion: nil)
}
@IBAction func unwindLocationCancel(segue:
UIStoryboardSegue){
}
@IBAction func
unwindLocationDone(segue:UIStoryboardSegue) {
if let viewController =
segue.source as? LocationViewController {
selectedCity =
viewController.selectedCity
if let location =
selectedCity {
headerView.lblLocation.text = location.full
}
}
}
}
// MARK: UICollectionViewDataSource
extension ExploreViewController: UICollectionViewDataSource
{
func collectionView(_ collectionView:
UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath:
IndexPath) -> UICollectionReusableView {
let header =
collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "header", for: indexPath)
headerView = header as?
ExploreHeaderView
return headerView
}
func collectionView(_ collectionView:
UICollectionView, numberOfItemsInSection section: Int) -> Int {
manager.numberOfItems()
}
func collectionView(_ collectionView:
UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell =
collectionView.dequeueReusableCell(withReuseIdentifier:
"exploreCell", for: indexPath) as! ExploreCell
let item = manager.explore(at:
indexPath)
cell.lblName.text = item.name
cell.imgExplore.image = UIImage(named:
item.image)
return cell
}
//
Can anyone see why this is producing this error?```
I am trying to create a number of cells on the iPhone screen. initially the cells default value is too small so I changed them in the size inspector. Visually I can see the new size is correct on the storyboard (2 per row), but when I run the simulator the cells are the original size. I have tried quitting both the simulator and the Xcode, but it still is incorrect.
Is this a bug?
How can I sort this out?
I am learning to code using iOS 14 Programming for beginners.
I was trying to place the Tab Bar buttons and confused the correct view in the scene. I was trying to add them to the Navigation Controller scene, but should have added them to the View controller scene. When I run the code the Cancel button should return to the previous scene, but does not.
How do I get rid of the actions that I have made by trying to add the tab bar to the wrong scene, assuming that this is what is causing the button not to work?
I have not added any code as I don't think that will serve any purpose at this stage.
I am trying to learn Xcode using iOS 14 Programming for Beginners (Packt Pub).
I am now working on the part that adds the pins to the MapView, but when I run the app the map button is unresponsive (Runtime error).
I get the following message in the Debug area:
__2021-07-25 16:08:23.919240+0100 EatOut[1420:21167] Metal API Validation Enabled
Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to '__C.MKAnnotation' (0x1c31e3888).
2021-07-25 16:08:24.003987+0100 EatOut[1420:21167] Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to '__C.MKAnnotation' (0x1c31e3888).
Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to 'C.MKAnnotation' (0x1c31e3888).
CoreSimulator 757.5 - Device: iPhone SE (2nd generation) (E06FF756-9D0E-45B8-BBF5-7B393524B880) - Runtime: iOS 14.5 (18E182) - DeviceType: iPhone SE (2nd generation)
I'm sure that this message means a lot to you experts, but as a beginner I haven't a clue!
The runtime error is in this func, in the final line:
func addMap(_ annontations: [RestaurantItem]) {
mapView.setRegion(manager.currentRegion(latDelta: 0.5, longDelta: 0.5), animated: true)
mapView.addAnnotation(manager.annotations as! MKAnnotation)
I get a build error on the final line if I do not apply the fix, which adds the as! MKAnnotation.
Is the error in the .plist or does the code need altering?
Please can you help?
Here is the full code for the swift file:
// MapViewController.swift
// EatOut
//
// Created by Tony Hudson on 15/07/2021.
//
import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
let manager = MapDataManager()
var selectedRestaurant: RestaurantItem?
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
initialise()
func initialise() {
manager.fetch { (annotations) in addMap(annotations)
}
}
func addMap(_ annontations: [RestaurantItem]) {
mapView.setRegion(manager.currentRegion(latDelta: 0.5, longDelta: 0.5), animated: true)
mapView.addAnnotation(manager.annotations as! MKAnnotation)
}
}
}
I am trying to learn swift and have a problem with segmented controls.
I have an IBAction which will use switch to select 'Male' or 'Female'.
Here is the code:
@IBAction func genderButton(_ sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex {
case 0:
userGender = "Female"
case 1:
userGender = "Male"
default:
return
}
}
However I get an error on the switch line:
Cannot find 'segmentedControl' in scope
I have looked on the web and the method looks OK to me, so why do I get this error?
I am learning Xcode/Swift from Ahmad Sahar's book and I have an exception error:
Exception NSException * "could not dequeue a view of kind: UICollectionElementKindCell with identifier restaurantCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard" 0x00006000002d06c0
name __NSCFConstantString * "NSInternalInconsistencyException" 0x00000001c3059170
reason __NSCFString * "could not dequeue a view of kind: UICollectionElementKindCell with identifier restaurantCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard" 0x00006000037a09c0
userInfo void * NULL 0x0000000000000000
reserved __NSDictionaryM * 2 key/value pairs 0x0000600000cf0480
The previous action that I did was to Ctrl + Drag from the exploreCell in the ExploreViewController Scene to the RestaurantListViewController Scene, creating a 'Show' Segue.
As I am a beginner I am not sure what the error is telling me?
Can someone help and show me where I am going wrong?
I am trying to learn Xcode using iOS 14 Programming for Beginners.
I have just created a new View Controller and created a Cocoa Touch class called RestaurantListViewController. In this I had to add 2 collection view stubs and an @IBoutlet var to the UICollectionView.
The book then instructs me to click on th View Controller in the
document outline, for the view controller I have just created, the click on the Identity Inspector to add the class, but it says no selection?
I can't see where I am going wrong?
The only warning I get is: Prototype collection view cells must have reuse indentifiers.
Here is the code for the class:
//
// RestaurantListViewController.swift
// EatOut
//
// Created by Tony Hudson on 22/05/2021.
//
import UIKit
class RestaurantListViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) - Int {
1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) - UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: "restaurantCell", for: indexPath)
}
}
Please can someone help?
I am trying to learn Xcode using iOS 14 Programming for Beginners.
I some how made an error when working through the instructions in the book. There are 2 navigation controllers and I connected a view controller to the wrong Navigation controller. When I realised my mistake I deleted the segue between the wrong Navigation Controller and the view controller. I then Ctrl + Dragged from the correct Nav Controller to the view controller and then created a new View Controller and did the same to this controller to the other Nav controller.
If I build the app every thing seems to work, except the Nav controller does not load the Map view when I click on the map icon, even though I have added the Map View to the View Controller.
Please help?
I am just started to learn iOS programming using Xcode.
This may seem a stupid question but I can't figure out how to set the screen to show the storyboard on the left and the swift code on the right. I am new to Xcode and am working through an exercise and need the Storyboard scenes and the specific swift file where I need to drag from the scene to the swift file. I have clicked on Assistant and the assistant editor should be set to Automatic LocationViewController.swift. When I click on Assistant with Storyboard selected, it says no Assistant results, if I click on the swift file in the tabs I get 2 copies of the swift file??
I have looked for a tutorial or info on the web but can't find any info on this topic.
Could someone please help?
I am new to programming and am struggling to find a solution to a problem in the exercise I am using to learn Xcode programming. I have even copied the code from the book website I am using.
I can stop the fatal error if I add a question mark or a Exclamation mark to the following line:
self.weightInput.delegate = self
self.heightInput.delegate = self
This is how I alter the lines:
self.weightInput!.delegate = self
self.heightInput!.delegate = self
The code builds in both cases and only produces a Fatal Error when I run the simulator without the unwrapping tags.
With the unwrapping added the simulator runs, but when I enter the data and click on the link nothing appears in the MY BMI text box.
I have not mastered debugging yet so don't know how to discover where the fault lies.
Can anyone help as I can't learn any more Xcode until I can see where my mistakes are.
Here is the full code:
// ViewController.swift
// BMI Calculator
//
// Created by Tony Hudson on 25/03/2021.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var weightInput: UITextField!
@IBOutlet weak var heightInput: UITextField!
@IBOutlet weak var BMIOutput: UITextField!
@IBOutlet weak var categoryOutput: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.weightInput.delegate = self //added either ! or ? here and don't get fatal error
self.heightInput.delegate = self //added either ! or ? here and don't get fatal error
}
@IBAction func calcBMI(_ sender: AnyObject) {
if let heightStr = heightInput.text {
if heightStr == "" {
return
}
else {
if let weightStr = weightInput.text {
if weightStr == "" {
return
}
else {
if let heightNum = Double(heightStr) {
if let weightNum = Double(weightStr) {
let BMI: Double = (weightNum) / (heightNum * heightNum)
BMIOutput.text = String(BMI)
print(BMI)
switch BMI {
case 1..15:
categoryOutput!.text = "Very severely underweight"
case 15...16:
categoryOutput!.text = "Severely underweight"
case 16..18.5:
categoryOutput!.text = "Underweight"
case 18.5..25:
categoryOutput!.text = "Normal"
case 25..30:
categoryOutput!.text = "Overweight"
case 30..35:
categoryOutput!.text = "Moderately obese"
case 35..40:
categoryOutput!.text = "Severely obese"
case 40..60:
categoryOutput!.text = "Very severely obese"
default:
return
}
} }
}
}
}
}
}
func textFieldShouldReturn(_ textField: UITextField) - Bool {
self.weightInput.resignFirstResponder()
self.heightInput.resignFirstResponder()
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I am trying to learn Xcode/Swift and have a problem.
I get the following error after build and after I have entered my age. Usually its a typo but this is not the case.
Here is the error:
[CalorieCounter.FirstViewController yourAge:]: unrecognized selector sent to instance 0x144b071
Here is the whole code:
//
// FirstViewController.swift
// CalorieCounter
//
// Created by Tony Hudson on 11/04/2021.
//
import UIKit
var userAge: Double?
var userWeight: Double?
var userGender: String = "Female"
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var yourAge: UITextField!
@IBOutlet weak var yourWeight: UITextField!
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBAction func genderButton(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
userGender = "Female"
case 1:
userGender = "Male"
default:
return
}
}
@IBAction func savePersonalInfo(_ sender: Any) {
userWeight = Double(yourWeight.text!)
userAge = Double(yourAge.text!)
}
}
Can anyone help me solve this problem