problems at nested hierarchy view using storyboard in Swift - swift

I'm beginner at Swift, so currently i organize most part of my app using storyboard.
I want to construct some view scrollable that contains textField and pickerView.
and each of them is stacked View, and then it is child view of view A.
and view A is child view of scrollView.
help you to understand more, i'll attach my app structure.
Anyway, when i run my apps, it represent well i want to achieve, however, coudn't get any touch reaction.
keyboard isn't popup when i touch textField, pickerView scroll isn't working. I think it's because of nested view, but have no idea how to solve.
plz help! And also glad give some advice learn Swift.
Thx in advance.
* edit 1) attach my code *
import UIKit
class ViewController:
UIViewController, UIPickerViewDataSource, UIPickerViewDelegate
{
#IBOutlet var outerView: UIView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var statePicker: UIPickerView!
#IBOutlet weak var innerView: UIView!
#IBOutlet weak var nameInputer: UITextField!
let states = ["Alaska", "Arkansas", "Alabama", "California", "Maine", "New York"]
override func viewDidLoad() {
super.viewDidLoad()
var scrollViewHeight:CGFloat = 0.0
for view in self.view.subviews as [UIView] {
scrollViewHeight += view.frame.size.height;
}
scrollView.contentSize = CGSize(width: view.frame.width, height: scrollViewHeight)
scrollView.contentInset = UIEdgeInsetsMake(20, 0, 20, 0)
statePicker.dataSource = self
statePicker.delegate = self
statePicker.isExclusiveTouch = true
scrollView.canCancelContentTouches = false
innerView.sendSubview(toBack: outerView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return states.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return states[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
statePicker.isHidden = true
}
}
* EDIT 2 : attach my story board *

Related

implementing Replace and Insert Buttons in Xcode/Swift

I am new to xCode and confused about implementing the following two things to the replace button and insert button. Can someone please helpWhen you press the
“replace” button, the item selected in the picker should be replaced by the contents of the text field (blank if
nothing in the text field). When you press “insert”, the contents of the text field should be added to the data for
the picker, after the item currently selected, and the new, added, item should be shown in the picker as the
selected item (so the previously selected item would be immediately above it on the picker’s display at that
point).
class ViewController: UIViewController {
#IBOutlet weak var countryTextField: UITextField!
#IBOutlet weak var selectButton: UIButton!
#IBOutlet weak var replaceButton: UIButton!
#IBOutlet weak var insertButton: UIButton!
let countries = ["USA", "MEXICO", "CANADA"]
var pickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
countryTextField.inputView = pickerView
countryTextField.textAlignment = .center
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countries.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return countries[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
countryTextField.text = countries[row]
countryTextField.resignFirstResponder()
}
}
Create #IBAction for your Buttons from xib and add conditions accordingly. It will look like these-
#IBAction func insertAction(sender: UIButton){
// write code for insert
}
#IBAction func replaceAction(sender: UIButton){
// write code for replace
}

How to use multiple UIPickerViews in one view controller

I am trying to set up 2 UIPickerViews in 1 view controller. I have not been able to find resources that solve my problem.
I have tried following the answer from Diavel Rider on How to use 2 UIPickerView's in one View Controller?. I got some errors from that. I have also tried adding tags but was not able to successfully do that. I am using Swift 4.
Here is the code of my view controller:
import UIKit
class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ foodTypeUIPickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var countrows : Int = nutritionPickerData.count
if pickerView == foodTypeUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
countrows = self.foodTypePickerData.count
}
return countrows
}
func pickerView(_ foodTypeUIPickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == nutritionUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
let titleRow = nutritionPickerData[row]
return titleRow
} else if pickerView == foodTypeUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
let titleRow = foodTypePickerData[row]
return titleRow
}
return ""
}
#IBOutlet weak var nutritionUIPickerView: UIPickerView!
#IBOutlet weak var foodTypeUIPickerView: UIPickerView!
var nutritionPickerData = ["Protein", "Fiber", "Iron", "Fat", "Sodium", "Calcium/Vitamin D", "Energy", "Carbohydrates", "Cholestorol"]
var foodTypePickerData = ["Fruits", "Vegetables", "Legumes and Beans", "Grain", "Meat", "Dairy"]
#IBAction func submitUIButton(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.nutritionUIPickerView.delegate = self
self.nutritionUIPickerView.dataSource = self
self.foodTypeUIPickerView.delegate = self
self.foodTypeUIPickerView.dataSource = self
}
}
I need to use 2 picker views in 1 view controller. How do I do this?
You are referencing a non-existent variable named pickerView. You should update the parameter name to pickerView to avoid issues.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == foodTypeUIPickerView {
return self.foodTypePickerData.count
} else {
return self. nutritionPickerData.count
}
}
Make a similar change to the other delegate/data source methods.
You should separate your data sources and delegates and not put them inside your view controller. Set those as the delegate and datasource. Code written in swift 4.2 xcode 10.1
class ViewController: UIViewController {
#IBOutlet weak var foodPicker: UIPickerView!
#IBOutlet weak var nutritionPicker: UIPickerView!
var foodData = FoodData()
var nutritionData = NutritionData()
override func viewDidLoad() {
super.viewDidLoad()
foodPicker.delegate = foodData
foodPicker.dataSource = foodData
nutritionPicker.delegate = nutritionData
nutritionPicker.dataSource = nutritionData
}
#IBAction func actionButton(_ sender: UIButton) {
let food = foodPicker.delegate?.pickerView!(foodPicker, titleForRow: foodPicker.selectedRow(inComponent: 0), forComponent: 0)
let nutrition = nutritionPicker.delegate?.pickerView!(nutritionPicker, titleForRow: nutritionPicker.selectedRow(inComponent: 0), forComponent: 0)
print("You picked: \(food) and \(nutrition)")
}
}
class FoodData: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
var foodTypePickerData = ["Fruits", "Vegetables", "Legumes and Beans", "Grain", "Meat", "Dairy"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return foodTypePickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return foodTypePickerData[row]
}
}
class NutritionData: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
var nutritionPickerData = ["Protein", "Fiber", "Iron", "Fat", "Sodium", "Calcium/Vitamin D", "Energy", "Carbohydrates", "Cholestorol"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return nutritionPickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return nutritionPickerData[row]
}
}

Using picker view with UIButton to open a new TableView

I have a picker view and tableviews for each picker row programmed and I'd like to connect them via a UIButton. Any suggestions for a swift function to connect the Pickerview row with the botton to open that picker's table? (code below)
Thanks!
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var Picker1: UIPickerView!
var Array = ["G: Classroom friendly", "PG-13: Swear words OK(no sexual innuendo)", "R: Anything goes!"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Picker1.delegate = self
Picker1.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Array[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Array.count
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
#IBAction func Submit(_ sender: Any) {
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
#IBAction func ContinueBotton(_ sender: UIButton) {
}
}
class ViewController1: UITableViewController {
#IBOutlet var ViewController1: UITableView!
var GRating = [GN]()

making a drop-down list in Swift 3

I'm trying to make drop-down list where picker view is not visible until user clicks on textfield. Then picker view disappears after user makes selection from pickerView. Currently, the picker View does not show up at all when I click on textfield.
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var textBox: UITextField!
#IBOutlet weak var pickerView: UIPickerView!
var choices = ["SortBy:", "Date(ascending)", "Date(descending)","Calories Burned(descending)","Duration(descending)"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
self.view.endEditing(true)
return choices[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return choices.count
}
fun pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.textBox.text = self.choices[row]
self.pickerView.isHidden = true
print("hello")
}
func textFieldDidBeginEditing(TextField: UITextField){
if TextField == self.textBox {
self.pickerView.isHidden = false
TextField.endEditing(true)
}
}
override func viewDidLoad() {
self.pickerView.isHidden = true
super.viewDidLoad()
}
}
try this :
override func viewDidLoad() {
self.pickerView.isHidden = true
super.viewDidLoad()
self.textBox.delegate = self
self.pickerView.delegate = self
}

EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode=0x0)

I'm creating a temperature converter. When I run the application; enter a temperature, select which conversion and click convert. An error comes up.
THE ERROR IS: EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode=0x0)
This is my code for ViewController:
import UIKit
class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
#IBOutlet weak var orginalValue: UITextField!
#IBOutlet weak var convertFrom: UIPickerView!
let pickerData = ["Celsius", "Fahrenheit"]
override func viewDidLoad() {
super.viewDidLoad()
convertFrom.dataSource = self
convertFrom.delegate = self
}
#IBOutlet weak var labelConvertFrom: UILabel!
#IBOutlet weak var convertTo: UIPickerView!
#IBOutlet weak var labelConverTo: UILabel!
#IBOutlet weak var answer: UILabel!
#IBAction func convertButton(sender: AnyObject) {
let a = Double(orginalValue.text!)
let tempConvertM = TempConvert(temp: a!)
answer.text = String(tempConvertM.convert())
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
labelConvertFrom.text = pickerData[row]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is where I'm getting the error.
TempConverterModel.swift
import Foundation
extension ViewController{
class TempConvert{
var temp:Double
var view = ViewController()
init (temp:Double){
self.temp = temp
}
func convert()->Double{
if(view.labelConvertFrom.text == "Celsius"){ -->ERROR IS HIGHLIGHTED HERE <--
view.labelConverTo.text = "Fahrenheit"
return (temp-32)/1.8000; //fahrenheit formula
}
else{
view.labelConverTo.text = "Celsius"
return (temp*1.8000)+32; //celsius formula
}
}
}
}
I don't know what I'm doing wrong. I want to check the text in labelConvertFrom and check if it equals to "Celsius". IF it does not then return answer.
I would really appreciate anyones help. Thank you!
As par pointed out, you should be removing the enclosing extension ViewController { } and have your TempConvert as a separate class.
Also, instead of trying to access the ViewController's instance variables in TempConvert, you should be doing the comparisons in your convertButton() method in ViewController class itself and call the appropriate conversion method in TempConvert class.
A better approach is to have a stored property for "Celsius" and a computed property for "Fahrenheit" within your ViewController class. You can refer this link for Properties in Swift language
The problem broadly stems from this line in class TempConvert:
var view = ViewController()
Here you are initializing an empty view controller. The outlets you've defined such as labelConvertFrom are not hooked up to anything, so when you try to deference them here:
view.labelConvertFrom.*text
you crash (specifically, you crash where I put the * character). The reason you crash is because at that point, labelConvertFrom is nil.
To get this to work right, you'll need to initialize the ViewController using the initWithNibName:bundle: method, passing the correct nib filename and bundle id (which is probably just NSBundle.mainBundle()).
Doing this will allow your outlets to be hooked up properly and then they won't be nil when you try to use them.