App displays text with different characters swift - swift

I am making a chat app. When i send my messages or receive from other user they end up being displayed like this. What might be the issue? It works alright but sometimes it just changes the way the texts are displayed. Am not sure what am missing in this. Can anyone take a look at it. Kindly. Thanks in advance
Below is my code
class ChatController: UIViewController,UITextViewDelegate,UITableViewDataSource,UITableViewDelegate,UIGestureRecognizerDelegate{
#IBOutlet weak var txtViewBottomConstraints: NSLayoutConstraint!
#IBOutlet weak var viewTextViewContainer: ViewCustom!
#IBOutlet weak var txtViewContainerHeightConstraints: NSLayoutConstraint!
#IBOutlet weak var txtViewHeightConstraints: NSLayoutConstraint!
#IBOutlet var lblUserName: UILabel!
#IBOutlet var userImg: UIImageView!
#IBOutlet weak var txtView: IQTextView!
#IBOutlet weak var tblViewChat: UITableView!
#IBOutlet weak var bottomViewBottomConstraints: NSLayoutConstraint!
#IBOutlet weak var btnSend: UIButton!
var grpId = String()
var getMessageTimer: Timer!
var scrollEnable : Bool = false
var imagePicker : UIImagePickerController? = nil
var imageData : Data?
var groupName = String()
var groupImage = String()
var isFromNotification = Bool()
var strId = String()
var objChatVM = ChatViewModel()
var getMessageId = String()
var userImage:URL? = nil
var userName = String()
override func viewDidLoad() {
super.viewDidLoad()
popWithSwipe()
txtView.autocorrectionType = .no
lblUserName.text = userName
/* if userImage != nil
{
userImg.kf.setImage(with:userImage)
}
else
{
userImg.image = UIImage(named: "user")
}*/
userImg.kf.setImage(with:userImage, completionHandler: {
(image, error, cacheType, imageUrl) in
if image != nil{
self.userImg.image = image
}
else{
self.userImg.image = #imageLiteral(resourceName: "user")
}
})
IQKeyboardManager.shared.enable = false
IQKeyboardManager.shared.enableAutoToolbar = false
tblViewChat.dataSource = self
tblViewChat.delegate = self
tblViewChat.estimatedRowHeight = 70.0
tblViewChat.rowHeight = UITableViewAutomaticDimension
txtView.delegate = self
// txtView.textContainerInset = UIEdgeInsets(top: 0, left: 2, bottom: 0, right: 2)
let tapGestuer = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
view.addGestureRecognizer(tapGestuer)
tapGestuer.delegate = self
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
if getMessageTimer != nil{
getMessageTimer.invalidate()
}
getMessageTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(getMessageApi), userInfo: nil, repeats: true)
IQKeyboardManager.shared.enable = false
IQKeyboardManager.shared.enableAutoToolbar = false
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
getMessageTimer.invalidate()
NotificationCenter.default.removeObserver(self)
}
// MARK:- Get messages from server
#objc func getMessageApi(){
objChatVM.getMessage(param:strId) {status in
if status{
self.tblViewChat.reloadData()
if(self.objChatVM.getNumberOfMessage() != 0){
self.tblViewChat.scrollToRow(at: IndexPath(item: self.objChatVM.getNumberOfMessage()-1, section: 0), at: .bottom, animated: false)
}
}
}
}
#objc func handleTap(sender: UITapGestureRecognizer) {
txtView.resignFirstResponder()
}
// Enable IQKEYBoard manager here for handle keyboard at other controller which has disabled in viewdidload or viewwillappear
override func viewDidDisappear(_ animated: Bool) {
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.enableAutoToolbar = true
}
// MARK:- Gesutrue Delegate Methods
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
// Handle here tap on table view and inside cell for dismiss keyboard while tap outside on the screen
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if (touch.view is SenderTblCell || touch.view is ReceiverTblCell ) {
return false
}
if (touch.view?.superview is SenderTblCell || touch.view?.superview is ReceiverTblCell) {
return false
}
if (touch.view?.superview?.superview is SenderTblCell || touch.view?.superview?.superview is ReceiverTblCell) {
return false
}
if (touch.view?.superview?.superview?.superview is SenderTblCell || touch.view?.superview?.superview?.superview is ReceiverTblCell) {
return false
}
if(touch.view?.superview?.isDescendant(of: SenderTblCell().contentView))! || (touch.view?.superview?.isDescendant(of: ReceiverTblCell().contentView))!{
return false
}
return true // handle the touch
}
// MARK:- KeyBoard will show
#objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
var safeArea = 0
if UIDevice().userInterfaceIdiom == .phone || UIDevice().userInterfaceIdiom == .pad{
switch UIScreen.main.nativeBounds.height {
case 2436:
bottomViewBottomConstraints.constant = -keyboardSize.height + 30
self.view.layoutIfNeeded()
default:
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
safeArea = Int(window?.safeAreaInsets.bottom ?? 0.0)
}
bottomViewBottomConstraints.constant = -keyboardSize.height + CGFloat(safeArea) - 10
self.view.layoutIfNeeded()
}
}
}
}
// MARK:- KeyBoard will hide
#objc func keyboardWillHide(notification: NSNotification) {
bottomViewBottomConstraints.constant = -30
self.view.layoutIfNeeded()
}
#IBAction func btnSendAction(_ sender: Any) {
let param = ["userId":strId,"message":txtView.text!]
objChatVM.sendMessage(param: param) { (status) in
self.txtView.text = ""
self.textViewDidChange(self.txtView)
}
}
//MARK:- TextView Delegate Methods
func textViewDidChange(_ textView: UITextView) {
if textView.text == ""{
//textView.translatesAutoresizingMaskIntoConstraints = true
// txtViewHeightConstraints.constant = 100.0
// btnSend.setImage(#imageLiteral(resourceName: "attachment"), for: .normal)
}else{
// btnSend.setImage(#imageLiteral(resourceName: "sendMsg"), for: .normal)
}
var frame : CGRect = textView.bounds
frame.size.height = textView.contentSize.height
print(frame)
if(frame.height >= 100.0){
textView.isScrollEnabled = true
}
else{
textView.isScrollEnabled = false
txtView.frame.size = frame.size
}
if textView.text == ""{
txtViewContainerHeightConstraints.constant = 50.0
txtViewBottomConstraints.constant = 5.0
txtView.updateConstraints()
viewTextViewContainer.updateConstraintsIfNeeded()
viewTextViewContainer.updateConstraints()
viewTextViewContainer.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
func textViewDidEndEditing(_ textView: UITextView) {
}
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
return true
}
// MARK:- TableView DataSource and Delegate Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objChatVM.getNumberOfMessage()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let messageUserId = objChatVM.getMessageUserFromId(index: indexPath.row)
print(UserViewModel.Shared().getUserId())
if(messageUserId == UserViewModel.Shared().getUserId()){
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "senderCell") as! SenderTblCell
cell.lblMessage.text = objChatVM.getMessage(index: indexPath.row)
cell.lblDate.text = objChatVM.getDateTime(index: indexPath.row)
return cell
}
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "receiverCell") as! ReceiverTblCell
cell.lblMessage.text = objChatVM.getMessage(index: indexPath.row)
cell.lblDate.text = objChatVM.getDateTime(index: indexPath.row)
cell.lblName.text = objChatVM.getFullNameOfUserFrom(index: indexPath.row)
let url = URL(string:objChatVM.getUserFromImage(index:indexPath.row))
cell.imgView.kf.indicatorType = .activity
cell.imgView.kf.setImage(with:url)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
txtView.resignFirstResponder()
}
// MARK: Side Menu Button Action
#IBAction func btnSideMenuActn(_ sender: UIButton) {
self.pushViewControl(ViewControl:"SideMenuController")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is how the message from my server in my logs looks like
message = "Am+good.+How+are+you+my+student%3F";

Use removingPercentEncoding and some of the text such as + doesn't seem to generated by urlEncoding if they are created by code then use both in combination:
message = "Am+good.+How+are+you+my+student%3F"
let decodedMessage = message.removingPercentEncoding?.replacingOccurrences(of: "+", with: " ")
print(decodedMessage)

Related

infinite loop when selected programmatically a cell

I have a tableview with a textfield in every row.
I need to reload the tableview and programmatically select the row the user had selected.
The user can write what he wants. The data will be deleted when the textfield's editing has ended and added when the textfield has begun editing.
But I get a infinite loop. Please cloud you help me?
My code :
import UIKit
class OptionsItemViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var textFiedlDelegate: UITextField? = nil
var categorySelected: Category?
var options: [String] = []
var nameOptions: [String] = []
var cellSelected: Int = 0
var viewHeight: CGFloat = 0
var selectedRow: IndexPath? = nil
var tableviewNeedToReload: Bool = false
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var keyboardAlwaysShow: UITextField!
#IBOutlet weak var newFeatureButton: UIBarButtonItem!
private let db = DataBase()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.textFiedlDelegate?.delegate = self
self.title = categorySelected!.name
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
db.getItemOptions(predicateFormat: "id == \(self.categorySelected!.id)", completion: { results in
self.categorySelected = results.first!
self.options = self.categorySelected!.options as! [String]
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(false)
self.viewHeight = self.view.frame.size.height
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(false)
var index = 0
while index < self.options.count {
if self.options[index] != "" {
index += 1
} else {
self.options.remove(at: index)
}
db.setCategoryOptions(category: self.categorySelected!, options: self.options, index: cellSelected)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func newFeature(_ sender: Any) {
if self.options.last != "" {
let indexPath: IndexPath = IndexPath(row: self.options.count, section: 0)
self.options.append("")
self.tableView.reloadData()
let cell = tableView(self.tableView, cellForRowAt: indexPath) as! CellItemOptions
cell.nameOptionsItem.becomeFirstResponder()
}
}
// MARK: - TableView Functions
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return options.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let option = options[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: CellItemOptions.identifier, for: indexPath) as! CellItemOptions
cell.nameOptionsItem.delegate = self
cell.configureCell(with: option)
return cell
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.cellSelected = options.index(of: textField.text!)!
let indexPath: IndexPath = IndexPath(row: self.cellSelected, section: 0)
self.tableView.reloadData()
let cell = self.tableView.cellForRow(at: indexPath) as! CellItemOptions
cell.nameOptionsItem.becomeFirstResponder()
}
func textFieldDidEndEditing(_ textField: UITextField) {
if textField.text! == "" {
if self.options[cellSelected] != "" {
db.setRemoveDetailsItem(category: self.categorySelected!, index: cellSelected)
}
self.options.remove(at: cellSelected)
} else {
self.options[cellSelected] = "\(textField.text!)"
db.setAddDetailsItem(category: self.categorySelected!, index: cellSelected)
}
db.setCategoryOptions(category: self.categorySelected!, options: self.options, index: cellSelected)
}
// MARK: - Keyboard
func keyboardWillShow(_ notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.size.height == self.viewHeight {
self.view.frame.size.height -= keyboardSize.height
}
}
}
func keyboardWillHide(_ notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y != self.viewHeight {
self.view.frame.size.height += keyboardSize.height
}
}
}
}
class CellItemOptions: UITableViewCell {
static let identifier = "OptionsItemCell"
#IBOutlet weak var nameOptionsItem: UITextField!
private let tableView = OptionsItemViewController()
func configureCell(with cell: String) {
nameOptionsItem.text = cell
}
}
EDIT :
The loop is due to the reload data...
Like I reload data in textFieldDidBeginEditing(), the view is reloaded more and more ... And I need to textFieldDidBeginEditing() to know the row selected by the user.

Update multiple UILabels in custom UITableViewCell with data from multiple corresponding UITextFields? Swift

I have a ViewController where a user can input their data in 4 UITextFields, populated by UIPickerViews, and when the user presses a save button the data is supposed to update the corresponding UILabels in the corresponding custom UITableViewCell.
See link below.
TableView and Input ViewControllers with arrows showing corresponding UILabels and UITextFields
Currently, with the code provided, all UILabels in the custom UITableViewCell display the same data.
See link below.
Current TableViewCell output in Simulator
I suspect I'm having issues with either this part in the RunFeedViewController
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "runFeedCell1", for: indexPath) as! Mountain1TableViewCell
cell.mountain1RunTypeLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunNameLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunSnowLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunDateLabel?.text = runFeedList[indexPath.item]
return (cell)
}
and/or this part in the Mountain1RunInputViewController
#IBAction func saveMountain1Run(_ sender: Any) {
if (mountain1RunDateTextField.text != "")
{
runFeedList.append(mountain1RunDateTextField.text!)
mountain1RunDateTextField.text = ""
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
}
}
What am I missing to make all 4 UILabels work with their corresponding UITextFields?.
Here is the code for the RunFeedViewController with the UITableView.
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
var runFeedList = [String]()
class RunFeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var runFeedListTable: UITableView!
var ref: DatabaseReference?
var databaseHandle: DatabaseHandle?
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return (runFeedList.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "runFeedCell1", for: indexPath) as! Mountain1TableViewCell
cell.mountain1RunTypeLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunNameLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunSnowLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunDateLabel?.text = runFeedList[indexPath.item]
return (cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){
if editingStyle == UITableViewCellEditingStyle.delete
{
runFeedList.remove(at: indexPath.row)
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
runFeedListTable.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
runFeedListTable.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.object(forKey: "runFeedList") != nil
{
runFeedList = UserDefaults.standard.object(forKey: "runFeedList") as! [String]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func logOutAction(_ sender: Any) {
if Auth.auth().currentUser != nil {
do {
try Auth.auth().signOut()
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
present(vc, animated: true, completion: nil)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
Here is the code for the Mountain1RunInputViewController where the user inputs the data in the 4 UITextFields.
import UIKit
var mountain1RunTypeArray = ["1", "2", "3", "4"]
var mountain1RunNameArray1 = ["1A","1B","1C", "1D"]
var mountain1RunNameArray2 = ["2A","2B","2C", "2D"]
var mountain1RunNameArray3 = ["3A","3B","3C", "3D"]
var mountain1RunNameArray4 = ["4A","4B","4C", "4D"]
var mountain1RunSnowArray = ["Good", "Bad"]
var mountain1SelectedItemsArray = [String]()
var mountain1RunTypeTextField: String = ""
var mountain1RunNameTextField: String = ""
var mountain1RunSnowTextField: String = ""
var mountain1RunDateTextField: String = ""
class Mountain1RunInputViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate{
var pickerView1 = UIPickerView()
var pickerView2 = UIPickerView()
var pickerView3 = UIPickerView()
var pickerView4 = UIDatePicker()
#IBOutlet weak var mountain1RunTypeTextField: UITextField!
#IBOutlet weak var mountain1RunNameTextField: UITextField!
#IBOutlet weak var mountain1RunSnowTextField: UITextField!
#IBOutlet weak var mountain1RunDateTextField: UITextField!
#IBAction func saveMountain1Run(_ sender: Any) {
if (mountain1RunDateTextField.text != "")
{
runFeedList.append(mountain1RunDateTextField.text!)
mountain1RunDateTextField.text = ""
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
}
}
override func viewDidLoad() {
super.viewDidLoad()
createToolbar()
pickerView1 = UIPickerView()
pickerView2 = UIPickerView()
pickerView3 = UIPickerView()
pickerView4 = UIDatePicker()
pickerView1.delegate = self
pickerView1.dataSource = self
pickerView2.delegate = self
pickerView2.dataSource = self
pickerView3.delegate = self
pickerView3.dataSource = self
pickerView1.tag = 0
pickerView2.tag = 1
pickerView3.tag = 2
pickerView4.tag = 3
self.mountain1RunTypeTextField.inputView = self.pickerView1;
self.mountain1RunNameTextField.inputView = self.pickerView2;
self.mountain1RunSnowTextField.inputView = self.pickerView3;
self.mountain1RunDateTextField.inputView = self.pickerView4;
pickerView4.addTarget(self, action: #selector(datePickerValueChanged(sender:)), for: .valueChanged)
pickerView4.datePickerMode = UIDatePickerMode.dateAndTime
}
func createToolbar() {
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton1 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker1))
let cancelButton2 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker2))
let cancelButton3 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker3))
let cancelButton4 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker4))
// Tool bar for 1st UIPickerView
let toolBar1 = UIToolbar()
toolBar1.sizeToFit()
toolBar1.barTintColor = .black
toolBar1.tintColor = .white
let doneButton1 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton1(sender:)))
toolBar1.setItems([cancelButton1,spaceButton,doneButton1], animated: false)
toolBar1.isUserInteractionEnabled = true
mountain1RunTypeTextField.inputAccessoryView = toolBar1
// Tool bar for 2nd UIPickerView
let toolBar2 = UIToolbar()
toolBar2.sizeToFit()
toolBar2.barTintColor = .black
toolBar2.tintColor = .white
let doneButton2 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton2(sender:)))
toolBar2.setItems([cancelButton2,spaceButton,doneButton2], animated: false)
toolBar2.isUserInteractionEnabled = true
mountain1RunNameTextField.inputAccessoryView = toolBar2
// Tool bar for 3rd UIPickerView
let toolBar3 = UIToolbar()
toolBar3.sizeToFit()
toolBar3.barTintColor = .black
toolBar3.tintColor = .white
let doneButton3 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton3(sender:)))
toolBar3.setItems([cancelButton3,spaceButton,doneButton3], animated: false)
toolBar3.isUserInteractionEnabled = true
mountain1RunSnowTextField.inputAccessoryView = toolBar3
// Tool bar for UIDatePicker
let toolBar4 = UIToolbar()
toolBar4.sizeToFit()
toolBar4.barTintColor = .black
toolBar4.tintColor = .white
let doneButton4 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton4))
toolBar4.setItems([cancelButton4,spaceButton,doneButton4], animated: false)
toolBar4.isUserInteractionEnabled = true
mountain1RunDateTextField.inputAccessoryView = toolBar4
}
func cancelPicker1(){
self.view.endEditing(true)
}
func cancelPicker2(){
self.view.endEditing(true)
}
func cancelPicker3(){
self.view.endEditing(true)
}
func cancelPicker4(){
self.view.endEditing(true)
}
// Done button for 1st UIPickerView
func doneButton1(sender: AnyObject) {
let row1 = pickerView1.selectedRow(inComponent: 0);
pickerView(pickerView1, didSelectRow: row1, inComponent:0)
view.endEditing(true)
}
// Done button for 2nd UIPickerView
func doneButton2(sender: AnyObject) {
let row2 = pickerView2.selectedRow(inComponent: 0);
pickerView(pickerView2, didSelectRow: row2, inComponent:0)
view.endEditing(true)
}
// Done button for 3rd UIPickerView
func doneButton3(sender: AnyObject) {
let row3 = pickerView3.selectedRow(inComponent: 0);
pickerView(pickerView3, didSelectRow: row3, inComponent:0)
view.endEditing(true)
}
// Done button for UIDatePicker
func doneButton4(){
let formatter = DateFormatter()
formatter.dateStyle = DateFormatter.Style.long
formatter.timeStyle = DateFormatter.Style.short
mountain1RunDateTextField.text = formatter.string(from: pickerView4.date)
self.view.endEditing(true)
}
func dismissKeyboard() {
self.view.endEditing(true)
}
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
pickerView4.datePickerMode = UIDatePickerMode.dateAndTime
mountain1RunDateTextField.text = dateFormatter.string(from: sender.date)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 0 {
return mountain1RunTypeArray.count
} else if pickerView.tag == 1 {
return mountain1SelectedItemsArray.count
} else if pickerView.tag == 2 {
return mountain1RunSnowArray.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.tag == 0 {
return mountain1RunTypeArray[row]
} else if pickerView.tag == 1 {
return mountain1SelectedItemsArray[row]
} else if pickerView.tag == 2 {
return mountain1RunSnowArray[row]
}
return ""
}
var selectedRow: Int = 0
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
if pickerView == pickerView1 {
mountain1RunTypeTextField.text = mountain1RunTypeArray[row]
switch row {
case 0:
mountain1SelectedItemsArray = mountain1RunNameArray1;
case 1:
mountain1SelectedItemsArray = mountain1RunNameArray2
case 2:
mountain1SelectedItemsArray = mountain1RunNameArray3
case 3:
mountain1SelectedItemsArray = mountain1RunNameArray4
default:
mountain1SelectedItemsArray = []
}
pickerView2.reloadAllComponents()
} else if pickerView == pickerView2 {
let item = mountain1SelectedItemsArray[row]
if mountain1SelectedItemsArray == mountain1RunNameArray1 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray2 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray3 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray4 {
mountain1RunNameTextField.text = item
}
}
if pickerView.tag == 2 {
mountain1RunSnowTextField.text = mountain1RunSnowArray[row]
}
}
}
Here is the code for corresponding prototype cell.
import UIKit
class Mountain1TableViewCell: UITableViewCell {
#IBOutlet weak var mountain1RunTypeLabel: UILabel!
#IBOutlet weak var mountain1RunNameLabel: UILabel!
#IBOutlet weak var mountain1RunSnowLabel: UILabel!
#IBOutlet weak var mountain1RunDateLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}

UITableView not displaying prototype cells

I am trying to make an app that connects to chromecast to play a video on TV, up till now I am still trying to display the video links using two view controllers, one contains a webview that makes the user gets the video page, the other is to display all video links inferred from the first view to make the user select which video to cast from the page. I am able to get the links but the problem is it doesn't want to be displayed in the table view cells. I have tried many methods but I noticed, for some reason the UITableViewDataSource methods are not being called at all. Here is the code:
ViewController.swift:
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
//MARK: Outlets
#IBOutlet weak var searchBar: UITextField!
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var cancelButton: UIButton!
#IBOutlet weak var searchBarTrailingConstraint: NSLayoutConstraint!
//MARK: Properties
static var videoURLs: [String] = []
//MARK: Methods
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
cancelButton.layer.cornerRadius = 5
cancelButton.isHidden = true
webView.delegate = self
}
func webViewDidFinishLoad(_ webView: UIWebView) {
var videoTag = ""
var embedTag = ""
let htmlCode = webView.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML")
let htmlTags = htmlCode!.components(separatedBy: "\n") as [String]
for tag in htmlTags{
var videoURL = ""
if tag.contains("<video") {
videoTag = tag.substring(from: tag.range(of: "<video")!.lowerBound)
videoTag = videoTag.substring(to: (videoTag.range(of: ">")?.upperBound)!)
if videoTag.contains("src"){
videoTag = tag.substring(from: tag.range(of: "src")!.upperBound)
for x in videoTag.characters{
if x == "\""{
continue
}else if x == "="{
continue
}else if x == ">"{
break
}else{
videoURL.append(x)
}
}
}
ViewController.videoURLs.append(videoURL)
}
if tag.contains("<embed") {
embedTag = tag.substring(from: tag.range(of: "<embed")!.lowerBound)
embedTag = embedTag.substring(to: (embedTag.range(of: ">")?.upperBound)!)
if embedTag.contains("src"){
embedTag = tag.substring(from: tag.range(of: "src")!.upperBound)
for x in embedTag.characters{
if x == "\""{
continue
}else if x == "="{
continue
}else if x == ">"{
break
}else{
videoURL.append(x)
}
}
}
ViewController.videoURLs.append(videoURL)
}
}
NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "Done")))
}
//MARK: Actions
#IBAction func cancelPressed() {
cancelButton.isHidden = true
searchBarTrailingConstraint.constant = 0.0
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
searchBar.resignFirstResponder()
}
#IBAction func searchBarPressed() {
searchBarTrailingConstraint.constant = (cancelButton.frame.width + 8.0) * -1
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
cancelButton.isHidden = false
}
#IBAction func returnButtonPressed(_ sender: UITextField) {
cancelPressed()
if let url = URL(string: sender.text!){
if UIApplication.shared.canOpenURL(url){
let request = URLRequest(url: url)
webView.loadRequest(request)
}else{
let googleSearchURL = URL(string: "https://www.google.com/search?client=safari&q=\(url)&ie=UTF-8&oe=UTF-8")
let request = URLRequest(url: googleSearchURL!)
webView.loadRequest(request)
}
}else{
var searchString: [String] = []
var searchWord = ""
for x in (sender.text?.characters)!{
if x == " "{
searchString.append(searchWord)
searchWord = ""
}else{
searchWord.append(x)
}
}
//For appending the last word not followed by a space
if !(searchString.last == searchWord){
searchString.append(searchWord)
}
var googleSearchURL = "https://www.google.com/search?client=safari&ie=UTF-8&oe=UTF-8&q="
for element in searchString{
googleSearchURL.append(element)
if !(searchString.last == element){
googleSearchURL.append("+")
}
}
let request = URLRequest(url: URL(string:googleSearchURL)!)
webView.loadRequest(request)
}
}
#IBAction func backButtonPressed(_ sender: UIButton) {
if webView.canGoBack{
webView.goBack()
}
}
#IBAction func forwardButtonPressed(_ sender: UIButton) {
if webView.canGoForward {
webView.goForward()
}
}
}
MediaTableViewController:
import UIKit
import AVFoundation
class MediaTableViewController: UIViewController, UITableViewDataSource {
var videoURLs: [String] = []
var videoScreenshots: UIImage!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(MediaTableViewController.replyToNotification), name: nil, object: nil)
self.tableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return videoURLs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("NOW!\n\n\n", indexPath.count)
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MediaTableViewCell
cell.videoImage.image = videoScreenshot(url: videoURLs[indexPath.count])
cell.videoURL.text = videoURLs[indexPath.count]
return cell
}
#objc func replyToNotification(){
videoURLs = ViewController.videoURLs
ViewController.videoURLs = []
}
// MARK: - Table view data source
func videoScreenshot(url: String) -> UIImage? {
let asset = AVURLAsset(url: URL(string: url)!)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
do {
let imageRef = try generator.copyCGImage(at: CMTime(value: asset.duration.value/2, timescale: asset.duration.timescale), actualTime: nil)
return UIImage(cgImage: imageRef)
}
catch let error as NSError
{
print("Image generation failed with error \(error)")
return nil
}
}
}
MediaTableViewCell.swift:
import UIKit
class MediaTableViewCell: UITableViewCell {
#IBOutlet weak var videoImage: UIImageView!
#IBOutlet weak var videoURL: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
Here is the Main.storyboard:
You do not call reloadData() thus the tableView is idle.
To fix this the following to MediaTableViewController:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
As I see you didn't implement tableView delegate
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(MediaTableViewController.replyToNotification), name: nil, object: nil)
self.tableView.delegate = self
self.tableView.dataSource = self
}
then add this method to your controller
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
hope this will help

CoreData not Persisting?

I am saving an exercise into core data and calling it into the table, this works in terms of carrying the info from the user input into the table, however the coredata doesnt persist so when i re open the app, the entry is lost.
It was actually working yesterday and seems to have broken, but I havent made a change that would effect this as far as im aware. The one thing i found when debugging is that when I loaded the app its meant to point at the sql database in my console, however its changed to a .configurationprofiles file? Could this be a cause and what would the fix be? I will include the code for the tableview and the code for the user entry form below to show the information flow. Let me know if any other data is needed to be added.
import Foundation
import UIKit
import CoreData
class ExerciseEditorController: UIViewController, UITextFieldDelegate {
var managedObjectContext: NSManagedObjectContext?
var userRepsCount = Int()
var userSetsCount = Int()
#IBOutlet weak var userExerciseName: UITextField!
#IBOutlet weak var userExerciseSetCounter: UILabel!
#IBOutlet weak var userExerciseRepsCounter: UILabel!
#IBOutlet weak var userExerciseWeight: UITextField!
#IBAction func userSetsStepper(_ sender: UIStepper) {
userExerciseSetCounter.text = Int(sender.value).description
self.userSetsCount = Int(sender.value)
}
#IBAction func userRepsStepper(_ sender: UIStepper) {
userExerciseRepsCounter.text = Int(sender.value).description
self.userRepsCount = Int(sender.value)
}
#IBAction func cancelExerciseEditor(_ sender: Any) {
self.performSegue(withIdentifier: "unwindToWorkoutDesignerWithSegue:", sender: self)
}
#IBAction func saveExerciseToWorkout(_ sender: Any) {
createExercise()
self.performSegue(withIdentifier: "unwindToWorkoutDesignerWithSegue:", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = (UIColor.customBackgroundGraphite())
userExerciseSetCounter.text = String(userSetsCount)
userExerciseRepsCounter.text = String(userSetsCount)
userExerciseWeight.delegate = self
userExerciseWeight.keyboardType = .numbersAndPunctuation
}
func createExercise() {
let userExerciseWeightSet = Double(self.userExerciseWeight.text!) //make this safe!
guard let managedObjectContext = managedObjectContext else { return }
let userExercise = UserExercise(context: managedObjectContext)
userExercise.name = userExerciseName.text
userExercise.sets = Int64(userSetsCount)
userExercise.reps = Int64(userRepsCount)
userExercise.weight = userExerciseWeightSet! //make this safe!
userExercise.createdAt = Date().timeIntervalSince1970
}
func animateTextField(textField: UITextField, up: Bool) {
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up {
movement = movementDistance
}
else {
movement = -movementDistance
}
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.animateTextField(textField: textField, up:true)
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.animateTextField(textField: textField, up:false)
}
}
And this is the tableview:
import Foundation
import UIKit
import CoreData
class WorkoutDesignerController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate {
#IBAction func unwindToWorkoutDesigner(segue: UIStoryboardSegue) {}
#IBOutlet weak var workoutDesignerTable: UITableView!
#IBOutlet weak var tapToAddExercise: UILabel!
#IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
#IBAction func cancelWorkoutDesigner(_ sender: Any) {
self.performSegue(withIdentifier: "unwindToTemplatesWithSegue", sender: self)
}
private let persistentContainer = NSPersistentContainer(name: "Lift")
override func viewDidLoad() {
super.viewDidLoad()
setupView()
workoutDesignerTable.delegate = self
workoutDesignerTable.dataSource = self
view.backgroundColor = (UIColor.customBackgroundGraphite())
persistentContainer.loadPersistentStores { (persistentStoreDescription, error) in
if let error = error {
print("Unable to Load Persistent Store")
print("\(error), \(error.localizedDescription)")
} else {
self.setupView()
do {
try self.fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("Unable to Perform Fetch Request")
print("\(fetchError), \(fetchError.localizedDescription)")
}
self.updateView()
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let userExercises = fetchedResultsController.fetchedObjects else { return 0 }
return userExercises.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? RoutineTableViewCell else {
fatalError("Unexpected Index Path")
}
cell.backgroundColor = UIColor.customBackgroundGraphite()
cell.textLabel?.textColor = UIColor.white
let userExercise = fetchedResultsController.object(at: indexPath)
cell.nameLabel.text = userExercise.name
cell.repsLabel.text = String(userExercise.reps)
cell.setsLabel.text = String(userExercise.sets)
cell.weightLabel.text = String(userExercise.weight)
return cell
}
private func setupView() {
setupMessageLabel()
updateView()
}
private func setupMessageLabel() {
tapToAddExercise.text = "Tap + To Add An Exercise To The Routine"
}
fileprivate func updateView() {
var hasUserExercises = false
if let UserExercise = fetchedResultsController.fetchedObjects {
hasUserExercises = UserExercise.count > 0
}
workoutDesignerTable.isHidden = !hasUserExercises
tapToAddExercise.isHidden = hasUserExercises
activityIndicatorView.stopAnimating()
}
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserExercise> = {
// Create Fetch Request
let fetchRequest: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
// Configure Fetch Request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: true)]
// Create Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addNewExerciseSegue" {
if let destinationViewController = segue.destination as? ExerciseEditorController {
// Configure View Controller
destinationViewController.managedObjectContext = persistentContainer.viewContext
}
}
}
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
workoutDesignerTable.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
workoutDesignerTable.endUpdates()
updateView()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch (type) {
case .insert:
if let indexPath = newIndexPath {
workoutDesignerTable.insertRows(at: [indexPath], with: .fade)
}
break;
default:
print("...")
}
}
}
You need to call context.save().

How to add a notification?

I want to add a local notification in my project. In the DetailViewController, I have two labels with date and hour.
Is it possible to add a notification based on this date and hour? If yes, can you explain how to set it?
Code:
DetailViewController :
import UIKit
class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: - Outlet
#IBOutlet var imageProfilo: UIImageView!
#IBOutlet var labelNome: UILabel!
#IBOutlet var pillsTable: UITableView!
// MARK: - Variabili
var profilo: ProfiloModel!
// MARK: - Metodi standard del controller
override func viewDidLoad() {
super.viewDidLoad()
pillsTable.dataSource = self
pillsTable.delegate = self
imageProfilo.layer.cornerRadius = 30
DataManager.sharedInstance.detail = self
if let test = profilo {
//title = profilo!.nome
labelNome.text = profilo!.nome
imageProfilo.image = profilo!.immagine
if profilo!.immagine.size.width > profilo!.immagine.size.height {
imageProfilo.image = UIImage(CGImage: profilo!.immagine.CGImage, scale: 1.0, orientation: UIImageOrientation.Right)
} else {
imageProfilo.image = profilo!.immagine
}
} else {
if !DataManager.sharedInstance.storage.isEmpty {
profilo = DataManager.sharedInstance.storage[0]
//title = profiloSos.nome
labelNome.text = profilo.nome
imageProfilo.image = profilo.immagine
if profilo.immagine.size.width > profilo.immagine.size.height {
imageProfilo.image = UIImage(CGImage: profilo.immagine.CGImage, scale: 1.0, orientation: UIImageOrientation.Right)
} else {
imageProfilo.image = profilo.immagine
}
} else {
return
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UITableView
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return profilo.therapyArra.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! PillsCell
var terapia = profilo.therapyArra[indexPath.row]
cell.nomeMedicina.text = terapia.nomeMedicina
cell.data.text = terapia.data
cell.ora.text = terapia.ora
cell.dosaggio.text = terapia.dosaggio
return cell
}
// MARK: - Azioni
// MARK: - Metodi
// MARK: - Navigazione
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "terapia" {
var cell = sender as! UITableViewCell
if let indexPath = self.pillsTable.indexPathForRowAtPoint(cell.center) {
var controller = segue.destinationViewController as! PillsViewController
controller.therapy = profilo.therapyArra[indexPath.row]
}
} else if segue.identifier == "addtherapy" {
var controller = segue.destinationViewController as! AddPillsController
controller.profilo = profilo
}
}
}'
PillsCell :
'import UIKit
class PillsCell: UITableViewCell {
#IBOutlet var nomeMedicina: UILabel!
#IBOutlet var ora: UILabel!
#IBOutlet var data: UILabel!
#IBOutlet var dosaggio: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
PillsModel :
import UIKit
class PillsModel: NSObject, NSCoding {
var nomeMedicina :String!
var data :String!
var ora :String!
var dosaggio :String!
init(nomeMedicinaIn:String, dataIn:String, oraIn:String, dosaggioIn:String) {
nomeMedicina = nomeMedicinaIn
ora = oraIn
data = dataIn
dosaggio = dosaggioIn
}
internal required init(coder aDecoder: NSCoder) {
self.nomeMedicina = aDecoder.decodeObjectForKey("nomeMedicina") as! String
self.ora = aDecoder.decodeObjectForKey("ora") as! String
self.data = aDecoder.decodeObjectForKey("data") as! String
self.dosaggio = aDecoder.decodeObjectForKey("dosaggio") as! String
}
func encodeWithCoder(encoder: NSCoder) {
encoder.encodeObject(self.nomeMedicina, forKey: "nomeMedicina")
encoder.encodeObject(self.ora, forKey: "ora")
encoder.encodeObject(self.data, forKey: "data")
encoder.encodeObject(self.dosaggio, forKey: "dosaggio")
}
}
AddPillsController :
import UIKit
class AddPillsController: UIViewController, UITextFieldDelegate, CameraManagerDelegate {
#IBOutlet var fieldNomeMedicina: UITextField!
#IBOutlet var fieldData: UITextField!
#IBOutlet var fieldOra: UITextField!
#IBOutlet var fieldDosaggio: UITextField!
var profilo: ProfiloModel!
override func viewDidLoad() {
super.viewDidLoad()
fieldNomeMedicina.delegate = self
fieldData.delegate = self
fieldOra.delegate = self
// Vista accessoria per la tastiera
var keyboardToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 44))
keyboardToolbar.barStyle = UIBarStyle.BlackTranslucent
keyboardToolbar.backgroundColor = UIColor.redColor()
keyboardToolbar.tintColor = UIColor.whiteColor()
var flex = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var save = UIBarButtonItem(title: "Fatto", style: UIBarButtonItemStyle.Done, target: fieldDosaggio, action: "resignFirstResponder")
keyboardToolbar.setItems([flex, save], animated: false)
fieldDosaggio.inputAccessoryView = keyboardToolbar
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder() // chiudere la tastiera nei campi di testo
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func annulla(sender: UIButton) {
dismissViewControllerAnimated(true, completion: nil) // chiude una modal
}
#IBAction func salva(sender: UIButton) {
if fieldNomeMedicina.text.isEmpty &&
fieldData.text.isEmpty &&
fieldOra.text.isEmpty &&
fieldDosaggio.text.isEmpty{
//alertView che avverte l'utente che tutti i campi sono obbligatori
return
}
var therapy = PillsModel(nomeMedicinaIn: fieldNomeMedicina.text,
dataIn: fieldData.text,
oraIn: fieldOra.text,
dosaggioIn : fieldDosaggio.text)
profilo.therapyArra.append(therapy)
DataManager.sharedInstance.salvaArray()
DataManager.sharedInstance.detail.pillsTable.reloadData()
dismissViewControllerAnimated(true, completion: nil)
}
}
You should use UILocalNotification. Use your date and time to create a NSDate object and then setup your notification like this:
let notification = UILocalNotification()
notification.fireDate = ... // Add your date here
notification.alertBody = "Alert alert alert!!!"
UIApplication.sharedApplication().scheduleLocalNotification(notification)
Handle the notification in your AppDelegate by overriding the didReceiveLocalNotification method:
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
println(notification.alertBody); // "Alert alert alert!!!"
}