Jetpack Compose TextField weird behavior when deleting text - android-jetpack-compose

This video explains better, please watch: Video
The code is very simple:
#Composable
fun Main() {
var note by remember {
mutableStateOf(
LoremIpsum(40).values.first() //generate a random string that contains 40 words
)
}
TextField(value = note, onValueChange = { note = it })
}
I have tried pasting random strings and deleting them fast enough in a messaging app, to make sure that this problem does not cause by the soft keyboard/Google keyboard, and it's just working fine in the messaging app.
I don't understand why this could happen, could this be a bug with TextField?
You can download the project here, but basically, all the code has been posted above.

Related

How to unfocus from a WebView in UWP

I'm working on a UWP app that hosts a WebView which runs in a separate process.
var webView = new Windows.UI.Xaml.Controls.WebView(WebViewExecutionMode.SeparateProcess)
This results in a behavior that if the WebView has the focus, the containing app can't regain the focus by itself by simply trying to focus on a UI element.
The app supports keyboard shortcuts which may result in different elements getting the focus, but it's not working correctly when the focus is captured by the WebView. The target element seems to be getting the focus but it seems as if the process itself is not activated (as the real focus resides in a different process I suppose...).
I'm currently trying to activate the app programmatically through protocol registration in an attempt to regain focus.
I added a declaration in the app manifest for a custom protocol mycustomprotocol coupled with the following activation overload
protected override void OnActivated(IActivatedEventArgs args)
{
if (eventArgs.Uri.Scheme == "mycustomprotocol")
{ }
}
And the following code to invoke the activation:
var result = await Windows.System.Launcher.LaunchUriAsync(new Uri("mycustomprotocol:"));
Seems to be working only on some computers, on others (not while debugging the app, only when executed unattached) instead of regaining focus the app's taskbar icon just flashes orange.
I've created a sample project showing the problem and the semi working solution here
Any insight on any of this would be great.
I can reproduce your issue. I found that when we switch the focus with the mouse, the focus can be transferred to the TextBlock. So you could solve this question through simulating mouse input.
Please use the following code to instead FocusTarget.Focus(FocusState.Programmatic).
As follows:
InputInjector inputInjector = InputInjector.TryCreate();
var infoDown = new InjectedInputMouseInfo();
// adjust your mouse position to the textbox through changing infoDown.DeltaX,infoDown.DeltaY
infoDown.DeltaX = 10; //change
infoDown.DeltaY = -150; //change
infoDown.MouseOptions = InjectedInputMouseOptions.LeftDown;
var infoUp = new InjectedInputMouseInfo();
infoUp.DeltaX = 0;
infoUp.DeltaY = 0;
infoUp.MouseOptions = InjectedInputMouseOptions.LeftUp;
inputInjector.InjectMouseInput(new[] { infoDown, infoUp });
Note: If you use the input injection APIs, you need to add inputInjectionBrokered Capabilitiy in your Package.appxmanifest.
But this Capabilitiy is a restricted Capabilitiy, you can’t publish this app in store, which can’t pass the verification.
I've been in discussions with a WebView software engineer. The problem is that the separate process still wants to own focus if you try to move the focus away from the webview. His solution is to ask the other process' web engine to give up focus with the following call:
_= webView.InvokeScriptAsync("eval", new string[] { "window.departFocus('up', { originLeft: 0, originTop: 0, originWidth: 0, originHeight: 0 });" });
You can call it before trying to change the focus to your target. I ran various tests and it works consistently.

iOS Copy Paste phone from contacts to UITextField adds strange unicode characters

The simplified scenario is the following.
New project using Single View App template.
Add a UITextField to the ViewController.
Run the app and copy and paste a Contacts phone number [ej. John Appleseed one (888) 555-5512) ] to the UITextField.
The number will be added with a Unicode character at the beginning and at the end, getting like \u{e2}(888) 555-5512\u{e2} when exploring the variable while debugging.
This is really weird and in my opinion, not the intended behaviour.
Is this a bug or something that works intentionally this way?
Code:
Nothing complicated here. As described before, brand new project, add UITextField, add Button, and if button triggered print the result.
The print will show the phone just fine, just put a breakpoint in the print line and see the value of the phone var to see what I mean.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var phoneLabel: UITextField!
#IBAction func goButton(_ sender: UIButton) {
let text = phoneLabel.text ?? ""
print(text)
}
}
Tested in:
iOS 11.1 - iPhone X
Xcode 9.1
Steps with images:
This is what I got at the breakpoint line.
I had exactly the same issue recently. Interestingly enough what you see in the debugger is unfortunately not what is actually pasted.
If you copy the number to a different place and investigate it with your console for example you will get the following output:
>>> u"\U+202D(888) 5555-5512\U+202C"
u'\u202d(888) 5555-5512\u202c'
>>> name(u"\U+202D")
'LEFT-TO-RIGHT OVERRIDE'
>>> name(u"\U+202C")
'POP DIRECTIONAL FORMATTING'
So as you can see it is really two different invisible characters controlling the flow of the text.
In order to solve that I filtered out all unicode characters of the cF category. So you could do:
phoneLabel.text?.replacingOccurrences(of: "\\p{Cf}", with: "", options: .regularExpression)

Using reopened standard file descriptors in an iOS app with background capabilities?

I would like to be able to redirect my logging statements to a file so that I can retrieve them when my app runs standalone (i.e. is not attached to Xcode). I have discovered (thank you Stackoverflow) that freopen can be used to accomplish this.
If I create a new Xcode project and add the code to redirect stderr then everything works as expected.
However, when I add the redirection code to my existing, bluetooth project I am having trouble. The file is being created and I can retrieve it using iTunes or Xcode's Devices window, but it is of size 0. If I explicitly close the file then the text that I wrote actually makes it into the file. It is as though iOS is not flushing the file when the app is terminated. I suspect that the trouble stems from the fact that I have enabled background processing. Can anyone help me to understand this?
Here is my code:
let pathes = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
let filePath = NSURL(fileURLWithPath: pathes[0]).URLByAppendingPathComponent("Test.log")
freopen(filePath.path!, "a", stderr);
fputs("Hello, Samantha!\r\n", stderr);
struct StderrOutputStream: OutputStreamType {
static let stream = StderrOutputStream()
func write(string: String) {fputs(string, stderr)}
}
var errStream = StderrOutputStream.stream
print("Hello, Robert", toStream: &errStream)
fclose(stderr) // Without this the text does not make it into the file.
I'd leave this as a comment, but have you looked into NSFileHandle? It sounds like you just need a way to append data to the end of a text file, correct?
Once you have a handle with something like NSFileHandle(forWritingToURL:), you can use .seekToEndOfFile() and .writeData(_:). As a side note, you'll need to convert your String to Data before writing it.
Admittedly, this will probably end up being more lines of code, and you'll almost certainly need to take threading into consideration.

iOS 8.1 Swift Dictionary Error: EXC_BAD_ACCESS (XCode 6.1)

TLDR: I'm getting an EXC_BAD_ACCESS error using swift in XCode 6.1 building for iOS8.1. I believe the issue is likely a compiler error.
I am making an app wherein the user is allowed to add (Korean) words from a dictionary (in the English sense) to a word list. I have the following classes that define a word (with associated definitions, audio files, user-interaction statistics, etc.) and a word list (with an associated list of words and methods to add/remove words to the list, alphabetize the list, etc):
class Word: NSObject, NSCoding, Printable {
var hangul = String("")
var definition = String("")
// ...
}
class WordList: NSObject, NSCoding {
var title = ""
var knownWords = Dictionary<String,String> ()
// ...
func addWordToList(wordName: String, wordDefinition: String) {
// Debug statements
println("I am WordList \"\(self.title)\" and have the following knownWords (\(self.knownWords.count) words total): ")
for (_wordName,_wordDefinition) in self.knownWords {
println("\t\"\(_wordName)\" : \(_wordDefinition)")
}
println("\nI am about to attempt to add the word \"\(wordName)\" with definition \"\(wordDefinition)\" to the above dictionary")
// Add word to wordList, including the 'let' fix
fix_EXC_BAD_ACCESS_bug()
knownWords[wordName] = wordDefinition // EXC_BAD_ACCESS
}
func fix_EXC_BAD_ACCESS_bug() {
// This empty line attempts to solve a exc_bad_access compiler bug when adding a new value to a WordList dictionary
let newDic = self.knownWords
}
// ...
}
Next I have a UITableViewController with a UISearchBar that I use to display the dictionary (again in the English sense) of words to the user. The user adds words by tapping a button (which is displaying an image) on the right of each cell, which calls the #IBAction func addWord() in the viewController:
class AddingWordsToWordList_TableViewController: UITableViewController, UISearchResultsUpdating {
var koreanDictionary = KoreanDictionary() // Custom class with method 'getWord(index: Int)' to return desired Word
var filteredSearch = [Word]()
// ...
// Add word
#IBAction func addWord(sender: UIButton) {
// Add word
if self.resultSearchController.active {
let word = filteredSearch[sender.tag]
wordList.addWordToList(word.hangul, definition: word.definition) // Enter addWordToList() here
} else {
let word = koreanDictionary.getWord(sender.tag)
wordList.addWordToList(word.hangul, definition: word.definition)
}
// Set image to gray
sender.imageView?.image = UIImage(named: "add133 gray")
// Save results
wordList.save()
// Reload table data
tableView.reloadData()
}
// ...
At first the app compiles and seems to run fine. I can add a new word list and start adding words to it, until I add the 8th word. I (always on the 8th word) get a EXC_BAD_ACCESS error in (WordList) addWordToList with the following println information:
I am WordList "School" and have the following knownWords (7 words total):
"방학" : school vacation
"대학원" : graduate school
"학년" : school year
"고등학생" : high school student
"초등학교" : elementary school
"학생" : student
"학교" : school
I am about to attempt to add the word "대학생" with definition "college student" to the above dictionary
Note that the order in which I add the words appears irrelevant (i.e. the word "college student" can be added successfully if it is one of the first 7 words). There is nowhere in the code where I explicitly change behavior based on the number of words in a word list (except to display the words in a word list as cells in a UITableView), or any dependencies that would (to my knowledge) make the 8th word a special number. And indeed this number can change by using the let hack= solution (see below) to a different number, but for a particular build is always the same number.
At this point I'm at a complete loss of what to do. I'm relatively new to swift and have spent quite a few hours looking up how to fix exc_bad_access errors. I've come to the following point:
It seems exc_bad_access errors usually mean one of three things (http://www.touch-code-magazine.com/how-to-debug-exc_bad_access/)
An object is not initialized
An object is already released
Something else that is not very likely to happen
I don't feel like either 1 or 2 can be the case for me, as right before we get the access error we can print out the contents of the dictionary in question (knownWords). However, as is always the case it is highly likely I'm missing something obvious, so please let me know if this is indeed true.
If the error is caused by 3 above ("something else") I have tried the following:
(From EXC_BAD_ACCESS on iOS 8.1 with Dictionary and EXC_BAD_ACCESS when updating Swift dictionary after using it for evaluate NSExpression solutions)
I have tried different variations of the let stupidHack = scenario, and it does sometimes change the results, but only the number of entries allowed before crashing (i.e. I can sometimes get to the ~15th/16th entry in the dictionary before the error). I have not been able to find an actual, bug-free solution using this method, however.
I have rebuilt using both Release and Debug modes; the error appears in both. Note I am only using the simulator and do not have a developer's license to try it on an actual device.
I have turned off (set to "None") compiler optimization (it was already off for the Debug build anyway).
I have tried building to iOS 8.0 with the same error results.
Any way to get around this issue is appreciated. A let hack = solution is acceptable, but preferably a solution will at least guarantee to not produce the error in the future under different build conditions.
Thanks!

Sencha iOS picker bug

My app is nearly completed, but there's one bug which I have to get sorted before release. The app uses Cordova 3.4 and Sencha to build a "native" app for iOS and Android (the bug only relates to iOS)
Basically, when the picker value is changed, unless the user is quick enough in how they click Done, it reverts to the previous value - hard to explain! Here is a video showing the bug in action.
As mentioned before, this is only a problem on iOS (Android is fine). It is also worth noting that when there are two value options in other pickers in the app this bug does not exist. For example, the picker for time (hours & minutes) and date (day & month) do not have this bug - only single value pickers have the issue.
Any ideas?
I have just had to fix this issue within our product, and boy debugging on the iPhone is a right pain when you only have a Windows desktop!
Essentially what seemed to be happening was that when a slot's selection changed, the internal selectedIndex property was being updated, however the _value was not - and it seems that it's the _value that is being consulted.
I created a new slot class as follows, that overrides doItemTap to ensure that value is set appropriately (me._value = me.getValue(true);):
Ext.define('Ext.ux.FixedSlot', {
extend: 'Ext.picker.Slot',
xtype : 'fixedslot',
doItemTap: function(list, index, item, e, event) {
var me = this;
me.selectedIndex = index;
me.selectedNode = item;
me._value = me.getValue(true);
me.scrollToItem(item, true);
}
});
Then in my picker definition config (we have a class defined as a subclass of field.Select), I instructed it to use my new slot type (defaultType: 'fixedslot'):
Ext.define('Ext.ux.MyFixedPicker', {
extend: 'Ext.field.Select',
config : {
defaultPhonePickerConfig : { defaultType: 'fixedslot' }
}
});
I'm hoping that helps you avoid some of the pain of my last six hours! I still can't explain exactly why/where in the Sencha Touch source that's important, but for right now it appears to fix the problem and meet our packaging deadline!

Resources