I have a tableview that has names and text fields in the accessoryView position. With the following UITableViewDelegate method, I am calling onEdit and it calls a UIPickerView. The problem is, if I have more then 1 cell, it only populates the data in the last uitextfield no matter which textfield I click on. How do I allow data to go into the text field I am editing?
def tableView(tableView, cellForRowAtIndexPath: indexPath)
#reuseIdentifier ||= "CELL_IDENTIFIER"
cell = tableView.dequeueReusableCellWithIdentifier(#reuseIdentifier) || begin
UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:#reuseIdentifier)
end
picker = UIPickerView.alloc.initWithFrame([[0, self.view.frame.size.height / 2 + 50], [self.view.frame.size.width, self.view.frame.size.height]])
picker.delegate = self
picker.showsSelectionIndicator = true
#picker_field = UITextField.alloc.initWithFrame([[200,20],[150,40]])
#picker_field.placeholder = "Choose Location.."
#picker_field.delegate = self
#picker_field.inputView = picker
cell.textLabel.text = #list[indexPath.row]
cell.accessoryView = #picker_field
cell.selectedBackgroundView.backgroundColor = UIColor.redColor
#cell.selectionStyle = UITableViewCellSelectionStyleNone
cell
end
def pickerView(pickerView, numberOfRowsInComponent: component)
#choices_count
end
def pickerView(pickerView, titleForRow: row, forComponent: component)
#choices[row]
end
def pickerView(pickerView, didSelectRow: row, inComponent: component)
#picker_field.text = #choices[row]
#picker_field.resignFirstResponder
end
The solution came from putting more focus on the #picker_field becoming the firstResponder. Once I put an if statement stating the firstResponder it populates everytime.
def pickerView(pickerView, didSelectRow: row, inComponent: component)
if #picker_field = firstResponder
#picker_field.text = #choices[row]
#picker_field.resignFirstResponder
end
end
Related
I'm displaying my results on an interactive grid. I'd like to be able to select multiple rows and click an edit button that will open up an “edit” form. I am having a number of problems:
Retrieve the car IDs of the rows selected. (I am having trouble accessing column values, I can access item values)
Pass a collection or array of ids to the edit form.
Save the collection.
Added more code in answer box by accident...……..
I made some progress but I am a little stuck. I followed the oracle blog and it was vey helpful. So on the attribute of the region I added the following code:
function (config) {
var $ = apex.jQuery,
toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
toolbarGroup = toolbarData.toolbarFind("actions3");
toolbarGroup.controls.push(
{
type: "BUTTON",
action: "updateCar",
label: "Edit Selected Cars",
hot: true,
});
config.toolbarData = toolbarData;
config.initActions = function (actions)
{
// Defining the action for activate button
actions.add(
{
name: "updateCar",
label: "Edit Selected Cars",
action: updateCar
});
}
function updateCar(event, focusElement)
{
var i, records, model, record,
view = apex.region("ig_car").widget().interactiveGrid("getCurrentView");
var vid = "";
model = view.model;
records = view.getSelectedRecords();
if (records.length > 0)
{
for (i = 0; i < records.length; i++)
{
record = records[i];
//alert("Under Development " + record[1]);
vid = vid + record[1] + "||";
apex.item("P18_CAR").setValue(vid);// This is not needed just to test
//the output
// call next page
// pass array as sql source or directly on page
}
}
}
return config;
}
This works. A button is displayed and when selected it gets the values from the interactive grid. The part I am stuck is how to call the next page and pass the multiple values (2 columns) to the page to be displayed and in a query to do an update.
Thank you if you can help me accomplish this!
Let's say:
I have class String containing an empty string variable a
In page 1, I need to set variable a = "string here"
In page 2, I need to call the value of a
How can I do that?
from page 1
let nextview = self.storyboard?.instantiateViewController(withIdentifier: "Page2Identifier") as! Page1Controller
nextview.prevscreen = a
self.navigationController?.pushViewController(nextview, animated: true)
in Page 2
var prevscreen = ""
I have just changed my code to Swift 3 from swift 2.3. The following code is working fine with swift 2.3 but there is no effect with swift 3.
I want to develop a customise text editor. And let user to select text and change its color. For that i am using this code.
let selectedRange = textView.selectedRange
let currentAttr = textView.textStorage.attributes(at: selectedRange.location, effectiveRange: nil)
var attrName = NSForegroundColorAttributeName
if !isForeGround{
attrName = NSBackgroundColorAttributeName
}
if currentAttr[attrName] == nil || currentAttr[attrName] as! UIColor != selectedUIColor{
let dict = [attrName:selectedUIColor]
let currentFont = currentAttr[NSFontAttributeName]
let fontDescriptor = (currentFont! as AnyObject).fontDescriptor
let updatedFont = UIFont(descriptor: fontDescriptor!, size: 0.0)
let dict2 = [NSFontAttributeName: updatedFont]
textView.textStorage.beginEditing()
if currentAttr.count>0{
textView.textStorage.addAttributes(dict, range: selectedRange)
}else{
textView.textStorage.setAttributes(dict, range: selectedRange)
}
textView.textStorage.addAttributes(dict2, range: selectedRange)
textView.textStorage.endEditing()
}
Runs successfully but there is no effect on text color.
This worked for me.
First you need to catch your selected text, with:
let selectedText = textView.selectedRange
Then, you create the attribute:
let myAttribute = [ NSForegroundColorAttributeName: selectedUIColor]
And lastly:
textView.textStorage.addAttributes(myAttribute, range: selectedText)
This must be in an Action called by any sender
Hope it works also for you!
Regards
Selected text can be changed with
self.textView.tintColor = .red
I am looping through an array of string arrays. I am comparing the element at index 0 to the title of the button pressed on the page(ideally). But I am getting an Unresolved Identifier error, which means I am doing something wrong. How Can I compare the element in the loop to the title of the button made programatically on the page. Here is my code! The issue is with the function at the bottom, in the if statement that is in the for loop. I don't know how to say 'if this index position of the element is equal too the title of the button pressed'.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
var songArray: [Array<String>] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//connect to website
let url = URL(string:"*******")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil
{
print("error")
}
else
{
if let content = data
{
do
{
//download JSON data from php page, display data
let JSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! [[String]]
print(JSON)
//Make buttons with JSON array
var buttonY: CGFloat = 20
for song in JSON {
self.songArray.append(song)
let SongButton = UIButton(frame: CGRect(x: 50, y: buttonY, width: 250, height: 30))
buttonY = buttonY + 50 // 50px spacing
SongButton.layer.cornerRadius = 10 //Edge formatting for buttons
SongButton.backgroundColor = UIColor.darkGray //Color for buttons
SongButton.setTitle("\(song[0])", for: UIControlState.normal) //button title
SongButton.titleLabel?.text = "\(song[0])"
SongButton.addTarget(self,action: #selector(self.songButtonPressed(_:)), for: UIControlEvents.touchUpInside) //button press / response
self.view.addSubview(SongButton) // adds buttons to view
}
}
catch
{
}
}
}
}
task.resume()
print(songArray)
}
func songButtonPressed(_ sender:UIButton!) { // function for buttons
for song in songArray {
if "\(song[0])" == SongButton.titleLabel?.text {
let URL = NSURL(string: "\(song[1])")
let player = AVPlayer(url: URL! as URL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
}
}
}
}
My train of thought is to loop through the array of arrays, compare index position 0 to all button titles on the page, and if it matches, plus index position 2 into the AV player. Thanks for any help or advice on the logic behind my code, I am a beginner and I know this level of programming is a bit over my head
It's most likely
for song in songArray {
// the string interpolation "\()" is redundant
if song[0] == sender.titleLabel?.text { ... }
or maybe
if song[0] == sender.title { ... }
SongButton is not related to the action method.
Using a regular QComboBox populated with items, if currentIndex is set to -1, the widget is empty. It would be very useful to instead have an initial descriptive text visible in the combo box(e.g. "--Select Country--", "--Choose Topic--", etc.) which is not shown in the dropdown list.
I couldn't find anything in the documentation, nor any previous questions with answers.
It doesn't appear that case was anticipated in the Combo Box API. But with the underlying model flexibility it seems you should be able to add your --Select Country-- as a first "legitimate" item, and then keep it from being user selectable:
QStandardItemModel* model =
qobject_cast<QStandardItemModel*>(comboBox->model());
QModelIndex firstIndex = model->index(0, comboBox->modelColumn(),
comboBox->rootModelIndex());
QStandardItem* firstItem = model->itemFromIndex(firstIndex);
firstItem->setSelectable(false);
Depending on what precise behavior you want, you might want to use setEnabled instead. Or I'd personally prefer it if it was just a different color item that I could set it back to:
Qt, How do I change the text color of one item of a QComboBox? (C++)
(I don't like it when I click on something and then get trapped to where I can't get back where I was, even if it's a nothing-selected-yet-state!)
One way you can do something similar is to set a placeholder:
comboBox->setPlaceholderText(QStringLiteral("--Select Country--"));
comboBox->setCurrentIndex(-1);
This way you have a default that cannot be selected.
Leaving my solution here from PyQt5. Create a proxy model and shift all the rows down one, and return a default value at row 0.
class NullRowProxyModel(QAbstractProxyModel):
"""Creates an empty row at the top for null selections on combo boxes
"""
def __init__(self, src, text='---', parent=None):
super(NullRowProxyModel, self).__init__(parent)
self._text = text
self.setSourceModel(src)
def mapToSource(self, proxyIndex: QModelIndex) -> QModelIndex:
if self.sourceModel():
return self.sourceModel().index(proxyIndex.row()-1, proxyIndex.column())
else:
return QModelIndex()
def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex:
return self.index(sourceIndex.row()+1, sourceIndex.column())
def data(self, proxyIndex: QModelIndex, role=Qt.DisplayRole) -> typing.Any:
if proxyIndex.row() == 0 and role == Qt.DisplayRole:
return self._text
elif proxyIndex.row() == 0 and role == Qt.EditRole:
return None
else:
return super(NullRowProxyModel, self).data(proxyIndex, role)
def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex:
return self.createIndex(row, column)
def parent(self, child: QModelIndex) -> QModelIndex:
return QModelIndex()
def rowCount(self, parent: QModelIndex = ...) -> int:
return self.sourceModel().rowCount()+1 if self.sourceModel() else 0
def columnCount(self, parent: QModelIndex = ...) -> int:
return self.sourceModel().columnCount() if self.sourceModel() else 0
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
if not self.sourceModel():
return None
if orientation == Qt.Vertical:
return self.sourceModel().headerData(section-1, orientation, role)
else:
return self.sourceModel().headerData(section, orientation, role)