Display array contents in UITextView - uitextfield

I am trying to display my array contents in a UITextView. This should be simple. The array echoes using NSlog
(
(
"Point 1",
"Point 2",
Point3
)
)
using the following doesn't work as I know the array needs to be broken down.
cell.textField.text = arrayContents;
I am looking at how to cycle through the array and display the content in a UITextField? The array is stored in arrayContents

You can't do this with UITextField but it is possible in UITextView. Try this. If you used in textfield the output will be Point 1 Point 2 Point 3
textView.text = [YourArrayName componentsJoinedByString:#"\n "];

Related

Xcode UITest scrolling to the bottom of an UITableView

I am writing an UI test case, in which I need to perform an action, and then on the current page, scroll the only UITableView to the bottom to check if specific text shows up inside the last cell in the UITableView.
Right now the only way I can think of is to scroll it using app.tables.cells.element(boundBy: 0).swipeUp(), but if there are too many cells, it doesn't scroll all the way to the bottom. And the number of cells in the UITableView is not always the same, I cannot swipe up more than once because there might be only one cell in the table.
One way you could go about this is by getting the last cell from the tableView. Then, run a while loop that scrolls and checks to see if the cell isHittable between each scroll. Once it's determined that isHittable == true, the element can then be asserted against.
https://developer.apple.com/documentation/xctest/xcuielement/1500561-ishittable
It would look something like this (Swift answer):
In your XCTestCase file, write a query to identify the table. Then, a subsequent query to identify the last cell.
let tableView = app.descendants(matching: .table).firstMatch
guard let lastCell = tableView.cells.allElementsBoundByIndex.last else { return }
Use a while loop to determine whether or not the cell isHittable/is on screen. Note: isHittable relies on the cell's userInteractionEnabled property being set to true
//Add in a count, so that the loop can escape if it's scrolled too many times
let MAX_SCROLLS = 10
var count = 0
while lastCell.isHittable == false && count < MAX_SCROLLS {
apps.swipeUp()
count += 1
}
Check the cell's text using the label property, and compare it against the expected text.
//If there is only one label within the cell
let textInLastCell = lastCell.descendants(matching: .staticText).firstMatch
XCTAssertTrue(textInLastCell.label == "Expected Text" && textInLastCell.isHittable)
Blaines answer lead me to dig a little bit more into this topic and I found a different solution that worked for me:
func testTheTest() {
let app = XCUIApplication()
app.launch()
// Opens a menu in my app which contains the table view
app.buttons["openMenu"].tap()
// Get a handle for the tableView
let listpagetableviewTable = app.tables["myTableView"]
// Get a handle for the not yet existing cell by its content text
let cell = listpagetableviewTable.staticTexts["This text is from the cell"]
// Swipe down until it is visible
while !cell.exists {
app.swipeUp()
}
// Interact with it when visible
cell.tap()
}
One thing I had to do for this in order to work is set isAccessibilityElement to true and also assign accessibilityLabel as a String to the table view so it can be queried by it within the test code.
This might not be best practice but for what I could see in my test it works very well. I don't know how it would work when the cell has no text, one might be able to reference the cell(which is not really directly referenced here) by an image view or something else. It's obviously missing the counter from Blaines answer but I left it out for simplicity reasons.

XCUItest is not passing even though predicates seem valid

Here is my code -> https://github.com/patchthecode/XCTestBug
Here is my view ->
I am trying to capture the gray colored view.
It contains a label Ll and Button 11
This code captures the view
let p1 = NSPredicate(format: "label LIKE[c] %#","L1")
let views = app.otherElements.containing(p1)
This code also captures the view correctly
let p2 = NSPredicate(format: "label LIKE[c] %#","11")
let views = app.otherElements.containing(p2)
But this code fails to capture anything
let p1 = NSPredicate(format: "label LIKE[c] %#","L1")
let p2 = NSPredicate(format: "label LIKE[c] %#","11")
let comp = NSCompoundPredicate(andPredicateWithSubpredicates: [p1, p2])
let views = app.otherElements.containing(comp)
What am i doing wrong?
Even if the comp predicate would work, it would not capture the gray view. It would capture all elements that contain the "L1" and the "11" element. In your case it captures 2 elements: the ViewController's view and the gray view (because both contain the "L1" and the "11". So this is not the right way to capture the gray view.
The easiest part to capture the gray view would be to add an accessibility identifier to it (and enable Accessibility for that UIView). Then you can query the gray box easily with:
let grayBox = app.otherElements.matching(identifier: "grayBox").element(boundBy: 0)
Your NSCompoundPredicate solution does not work because the query is looking for elements that contain ONE label with the text "L1" AND "11". And because a UILabel can only have one text this always fails.

How do I limit NSTextView to 2 lines?

I'm trying to specify the number of lines for NSTextView. My designer is requesting 2 lines of text max. I've tried NSMutableParagraph style to add the ellipses truncation that I want, but with NSMutableParagraph I can only get NSTextView with 1 line and without NSMutableParagraph, I get a scrolling text with as many lines as needed to complete text.
var attributedString = NSMutableAttributedString(string: "This is my text, I can keep going for many characters")
var para = NSMutableParagraphStyle()
para.lineBreakMode = NSLineBreakMode.ByTruncatingTail
let globalAttributes = [
NSParagraphStyleAttributeName: para
]
let range = NSRange(location:0, length: attributedString.length)
attributedString.addAttributes(globalAttributes, range: range)
cellView.myTextView!.textStorage?.setAttributedString(attributedString)
I've tried height constraint on NSTextView. I've tried:
cellView.myTextView!.textContainer?.containerSize = NSMakeSize(300, 32)
I've tried creating IBOutlet for NSScrollView that NSTextView in within and adjusting its height. No luck with getting both 2 lines and truncation. Any help is greatly appreciated. I feel like I'm just missing a method or setup. Thanks!
From 10.11 you can use this
yourTextViewObj.textContainer.maximumNumberOfLines = 2;
You can use an NSTextField configured as a multi-line label. That means setting its cell's wraps property to true and, if desired, its truncatesLastVisibleLine to true.
For NSTextField (aka label) You can just do self.textField.maximumNumberOfLines = 2;
That's it.
Max number of lines is now a property of NSTextField
label.maximumNumberOfLines = 1;

UITextField not scrolling horizontally

I am trying to make a small calculator app.
When a UIButton is pressed, the Button title is added to a UITextField.
kind of:
myuitextfield.text = [myuitextfield.text stringByAppendingString:[button currentTitle];
When I reach the end of my textfield, the text gets truncated. How can I disable this, so the textfield starts scrolling automatically and allows adding more characters?
I tried every possible option in Interface Builder, without any luck.
Isn't the UITextField supposed to scroll automatically? I can see this behavior when a native keyboard is used and text is entered.
I have chosen UITextField, as I need only 1 Line.
To illustrate the Problem:
When I enter text using my custom UIButtons text gets truncated
When I tap the UITextField and enter text using the keyboard I can enter unlimited text and the text is not truncated.
If you are facing this issue on iOS7, I've managed to fix it after been inspired by this post. In my case I had a field for entering an email address and after reaching the edge, the user could carry on typing but the text would be invisible (off-field).
First, add a callback to your UITextField so that you can track a text change to the field:
[self.field addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
Then evaluate the size in pixels of the entered string as it is typed and change the text alignment from left to right when reaching the edge of the field area:
- (void)textFieldDidChange:(NSNotification *)aNotif{
float maxNumPixelsOnScreen = 235; // Change this value to fit your case
CGSize maximumSize = CGSizeMake(maxNumPixelsOnScreen + 10, 1);
NSString *aString = self.field.text;
CGSize stringSize = [aString sizeWithFont:fieldFont
constrainedToSize:maximumSize
lineBreakMode:NSLineBreakByWordWrapping];
self.field.textAlignment = NSTextAlignmentLeft;
if (stringSize.width >= maxNumPixelsOnScreen)
self.field.textAlignment = NSTextAlignmentRight;
}
Note:
self.field is the offending UITextField
maximumSize: I'm adding 10 the the width to be slightly over the limit defined
fieldFont is the UIFont used to render the text field
Hope it helps!
you have to add UITextview and limit the number of lines to 2.Textfield doesnt work with two lines.Textview is same as textfields except the delegates and some properties differ.

Xcode - How to get button to change label text multiple times

I am trying to have numbers change by different amounts, by the press of one button. I am new to xcode and do not know how to do this, any help would be nice.
I want the number to change to 15, but only when I press the button for a second time. Then, I would like, upon a third press, for the number to change 30.
press 1: from "0" to "5",
press 2: from "5" to "15",
press 3: from "15" to 30", I want to learn how to add different amounts
-(IBAction)changep1:(id) sender {
p1score.text = #"5";
if (p1score.text = #"5"){
p1score.text = #"15";
//Even if the above worked, I do not know how I would write the code to change it to 30. }
It sounds like you probably want to add a property to your view controller to store Player 1's score, something like this:
#property (nonatomic, assign) NSInteger p1Score;
Then in your init method, you can give this property an initial value:
self.p1Score = 0; // you can set this to any integral value you want
Then, in your button tap method (changep1) you can do something like this:
- (IBAction)changep1:(id)sender
{
// add 5 (or any value you want) to p1Score
self.p1Score = self.p1Score + 5;
// update the display text. in code below %d is replaced with the value of self.p1Score
p1score.text = [NSString stringWithFormat:#"%d", self.p1Score];
}

Resources