Microsoft speech recognizer stops recognizing - wpf

I am having trouble with the Microsoft speech recognizer. I am trying to make it constantly listen to me, and only after the word HELLO is recognized, it shows what I said. This part appears to be working, but after 15-20 seconds as the object "sre" is destroyed (as i think) the recognizer stops responding.
static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
List<string> words = new List<string>();
int count = e.Result.Words.Count;
for (int i = 0; i < count; i++)
{
words.Add(e.Result.Words[i].Text);
}
if (e.Result.Confidence > 0.7)
{
if (words[0].ToString() == "Hello")
{
switch (count)
{
case 2:
t.Text = words[1];
break;
case 3:
t.Text = words[1] + " " + words[2];
break;
}
}
}
}
private void InitializeSpeechGrammar()
{
t = UserMessage;
SpeechRecognitionEngine sre= new SpeechRecognitionEngine();
sre.SetInputToDefaultAudioDevice();
sre.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sre_SpeechRecognized);
var grammarBuilder = new GrammarBuilder();
grammarBuilder.Append(new Choices("Hello"));
grammarBuilder.AppendWildcard();
sre.BabbleTimeout = TimeSpan.FromSeconds(3);
sre.InitialSilenceTimeout = TimeSpan.FromSeconds(3);
var CommToRecognize = new Choices();
CommToRecognize.Add(new string[] { "Red", "Green", "Blue", "Yellow", "Grey" });
grammarBuilder.Append(CommToRecognize);
Grammar g = new Grammar(grammarBuilder);
sre.LoadGrammar(g);
sre.RecognizeAsync(RecognizeMode.Multiple);
}
So, there is the RecognizeMode.Multiple mode:
sre.RecognizeAsync(RecognizeMode.Multiple);
Should I be using this mode instead? Or is there something else that I am doing wrong?

Related

fixing non-null String must be provided to a Text widget

I'm quite new in flutter.
I am working on a quiz app and try to make every quiz has five questions
I faced some problems :
1- I don't want to repeat the same question in the same quiz.[my quiz also start with question number one every time].
2- Every time it reaches my question number ten [which in array] nine my app crash.
NOTE: I'm using a JSON file to store my questions.
int j = 1;
int i = 1;
var random_array;
genrandomarray() {
var distinctIds = [];
var rand = new Random();
for (int i = 1;;) {
distinctIds.add(rand.nextInt(10));
random_array = distinctIds.toSet().toList();
if (random_array.length < 10) {
continue;
} else {
break;
}
}
print(random_array);
}
setState(() {
if (j < 5) {
i = random_array[j];
j++;
} else {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(marks: marks),
));
}
disableAnswer = false;
});
genrandomarray() {
var rand = new Random();
make it choose random between questions
var distinctIds = [i = rand.nextInt(10) + 1];
for (int i = 0;;) {
to not crash when it reach to 10 question
distinctIds.add(rand.nextInt(10) + 1);
random_array = distinctIds.toSet().toList();
if (random_array.length < 10) {
continue;
} else {
break;
}
}
print(random_array);
}

dropdown error on device in codenameone

I am implementing drop-drown feature in my app. Its implemented using container with list of elements in it.
Suppose the drop down list has following items aa1, aa2, aa3, aa4 aa5 and so on. And if i search as 'aa' it displays items starting from 'aa', if I select aa5 from list, it takes aa1 and displays that. But whereas if I scroll the items and select its working fine. This problem occurring only on iOS device working perfectly fine on simulator.
the first picture depicts how drop down looks like, in second picture if I search 'ee', it gives list of items starting with 'ee'. If I select 'ee5', it sets to ee1 as shown in picture 3. Problem only on device. Any workaround for this?
So, please let me know whats the issue with this.
Thanks
[![enter image description here][1]][1]
private CustomList itemList;
class CustomList extends List {
int startYPos = -1;
long lastDiff = 0;
Timer t = null;
int draggingState = 0;
public CustomList() {
this.setTensileDragEnabled(false);
}
}
private class ButtonListener implements ActionListener {
public void actionPerformed(final ActionEvent evt) {
final Runnable rn = new Runnable() {
public void run() {
// Create and show a dialog to allow users to make a selection.
final UiBuilder uib = dm.UiBuilder();
dialog = (Dialog) uib.createContainer(DESIGNER_NAME_DIALOG_COMBOBOX_CONTAINER);
GenericSpinner itemSpinner = (GenericSpinner) uib.findByName(DESIGNER_NAME_DIALOG_COMBOBOX_GENERIC_SPINNER, dialog);
itemSpinner.setPreferredW(Display.getInstance().getDisplayWidth() * 4 / 5);
//remove from parent and replace with a linear list
Container parent = itemSpinner.getParent();
parent.removeComponent(itemSpinner);
// Add the searchable text field box
final TextField tf = (TextField)uib.findByName("Search", dialog);
tf.addDataChangedListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
Object[] items = model.getFilteredItems(tf.getText());
itemList.setModel(new DefaultListModel(items));
}
});
itemList = new CustomList();
itemList.getAllStyles().setBgTransparency(0);
itemList.setItemGap(0);
parent.addComponent(BorderLayout.CENTER, itemList);
final String[] items = model.getItems();
itemList.setModel(new DefaultListModel(items));
itemList.getStyle().setMargin(10, 10, 10, 10);
itemList.setFireOnClick(true);
itemList.setLongPointerPressActionEnabled(false);
ActionListener list = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (model.isUserEditable() && model.getItemCount() > 0) {
int i = itemList.getSelectedIndex();
if (i > items.length - 1) {
return;
}
itemList.getModel().setSelectedIndex(i);
model.onUserDataEntered((String) itemList.getModel().getItemAt(i));
String textToDisplay = (String) itemList.getModel().getItemAt(i);
button.setText(textToDisplay);
}
dialog.dispose();
}
};
itemList.addActionListener(list);
CommonTransitions tran = CommonTransitions.createEmpty();
dialog.setTransitionInAnimator(tran);
dialog.setTransitionOutAnimator(tran);
itemList.setRenderer(new ListRenderer());
//related to dialog to show list of items
//how much space do we really need???
if (cellHeight == 0) {
int dip = Display.getInstance().convertToPixels(1);
int siz = 2;
if (Display.getInstance().isTablet()) {
siz = 4;
}
siz *= 2;
cellHeight = siz * dip;
}
int heightRequired = cellHeight * (items.length + 8);
//is this too much for the screen - we will use 3/4 of the screen height max
int availableHeight = Display.getInstance().getDisplayHeight() * 3;
availableHeight /= 4;
if (heightRequired > availableHeight) {
int topPos = Display.getInstance().getDisplayHeight() / 8;
int bottomPos = topPos + availableHeight;
dialog.show(topPos, topPos, 40, 40);
}
else {
int topPos = (Display.getInstance().getDisplayHeight() - heightRequired) / 2;
int bottomPos = topPos + heightRequired;
dialog.show(topPos, topPos, 40, 40);
}
}
};
}
}
//new code using Multibutton implementation
final String[] listItems = model.getItems();
Display.getInstance().callSerially(() ->{
multiButton= new MultiButton();
multiButton.setTextLine1(s);
dialog.add(multiButton);
multiButton.addActionListener(e -> Log.p("you picked " + multiButton.getSelectCommandText(), Log.ERROR));
}
dialog.revalidate();
});
I would recommend using a Container and simple layout search as demonstrated by code such as this. The code below was taken from the Toolbar javadoc:
Image duke = null;
try {
duke = Image.createImage("/duke.png");
} catch(IOException err) {
Log.e(err);
}
int fiveMM = Display.getInstance().convertToPixels(5);
final Image finalDuke = duke.scaledWidth(fiveMM);
Toolbar.setGlobalToolbar(true);
Form hi = new Form("Search", BoxLayout.y());
hi.add(new InfiniteProgress());
Display.getInstance().scheduleBackgroundTask(()-> {
// this will take a while...
Contact[] cnts = Display.getInstance().getAllContacts(true, true, true, true, false, false);
Display.getInstance().callSerially(() -> {
hi.removeAll();
for(Contact c : cnts) {
MultiButton m = new MultiButton();
m.setTextLine1(c.getDisplayName());
m.setTextLine2(c.getPrimaryPhoneNumber());
Image pic = c.getPhoto();
if(pic != null) {
m.setIcon(fill(pic, finalDuke.getWidth(), finalDuke.getHeight()));
} else {
m.setIcon(finalDuke);
}
hi.add(m);
}
hi.revalidate();
});
});
hi.getToolbar().addSearchCommand(e -> {
String text = (String)e.getSource();
if(text == null || text.length() == 0) {
// clear search
for(Component cmp : hi.getContentPane()) {
cmp.setHidden(false);
cmp.setVisible(true);
}
hi.getContentPane().animateLayout(150);
} else {
text = text.toLowerCase();
for(Component cmp : hi.getContentPane()) {
MultiButton mb = (MultiButton)cmp;
String line1 = mb.getTextLine1();
String line2 = mb.getTextLine2();
boolean show = line1 != null && line1.toLowerCase().indexOf(text) > -1 ||
line2 != null && line2.toLowerCase().indexOf(text) > -1;
mb.setHidden(!show);
mb.setVisible(show);
}
hi.getContentPane().animateLayout(150);
}
}, 4);
hi.show();

Unity - my array is not updating its elements

I'm making my first app in Unity to learn English words and I got stuck.
I created and array like that:
public string[] words = {
"apple",
"banana",
"big",
"blue",
"book",
"one",
"two"
};
I'm using PlayerPrefs to save which array element I'm learning at the moment.
The problem is that I can't add or remove elements from this array. Whatever I do it always shows these 7 elements.
Can you please tell me why?
The thing is I don't want to add elements dynamically or within the script. I just want to expand my array manually by adding more elements, like this:
public string[] words = {
"apple",
"banana",
"big",
"blue",
"book",
"one",
"two",
"colours",
"green",
"orange",
"pencil",
"yellow",
"four",
"five",
"six",
"small",
};
The thing is that after changing array from my first post to this one, change takes no effect. Program still sees only 7 elements.
I tried to delete some elements and the result is the same. It looks like the program holds my array in memory or something....
Here is my complete code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour {
public static GameManager instance;
public bool isLearnOn;
public bool isFrontMenuActive;
public GameObject frontMenuEmpty;
Animator frontMenu;
Animator finishPanel;
//Tasks Elements
Image taskImage;
GameObject taskImageEmpty;
GameObject taskAllElementsEmpty;
GameObject taskTextEmpty;
Text taskText;
InputField taskInputField;
AudioSource taskAudio;
int randomWord;
int wordCount;
int allWordsCount;
int collectPoint;
Text pointsBoard;
Text hint;
public bool isHintShown;
GameObject hintTextEmpty;
int innerTaskCount;
public bool isFinishPanelOn;
void Awake(){
if (instance == null) {
instance = this;
}
}
void Start () {
collectPoint = (PlayerPrefs.GetInt ("points"));
isLearnOn = false;
//Variable assignment
//Tasks Elements
taskAllElementsEmpty = GameObject.Find ("TaskAllElementsEmpty");
taskImage = GameObject.Find ("TaskImage").GetComponent <Image>();
taskTextEmpty = GameObject.Find ("TaskTextEmpty");
taskText = GameObject.Find ("TaskText").GetComponent <Text>();
taskInputField = GameObject.Find ("TaskInputField").GetComponent <InputField>();
taskAudio = GameObject.Find ("GameManager").GetComponent <AudioSource>();
pointsBoard = GameObject.Find ("PointsBoard").GetComponent <Text>();
hint = GameObject.Find ("Hint").GetComponent <Text>();
hintTextEmpty = GameObject.Find ("HintTextEmpty");
finishPanel = GameObject.Find ("FinishPanel").GetComponent <Animator>();
taskImageEmpty = GameObject.Find ("TaskImageEmpty");
frontMenuEmpty = GameObject.Find ("FrontMenuEmpty");
frontMenu = GameObject.Find ("FrontMenuEmpty").GetComponent <Animator>();
pointsBoard.text = collectPoint.ToString ();
allWordsCount = words.Length;
Debug.Log (allWordsCount);
isFrontMenuActive = false;
FrontMenuShowHide ();
taskAllElementsEmpty.SetActive (false);
isHintShown = false;
hint.text = "";
innerTaskCount = 0;
isFinishPanelOn = false;
//TODO Disable finisih panel
}
void Update () {
if (isLearnOn == true) {
if (wordCount < allWordsCount) {
if ((taskInputField.text == words [wordCount]) && innerTaskCount == 0) {
Task1 ();
taskText.text = "";
taskInputField.placeholder.GetComponent<Text>().text = "What is it?";
innerTaskCount = 1;
}
else if ((taskInputField.text == words [wordCount]) && innerTaskCount == 1) {
Task1 ();
taskText.text = "";
taskInputField.placeholder.GetComponent<Text>().text = "Listen and type the word down";
taskImageEmpty.SetActive (false);
innerTaskCount = 2;
}
else if ((taskInputField.text == words [wordCount]) && innerTaskCount == 2){
if (isHintShown == false) {
CollectPoints ();
NextTask ();
Debug.Log (wordCount);
innerTaskCount = 0;
} else {
NextTask ();
innerTaskCount = 0;
}
}
} else {
if(isFinishPanelOn == false){
HideFinishPanel ();
wordCount = 0;
}
}
} else {
if (taskInputField.text == words [randomWord]) {
if (isHintShown == false) {
CollectPoints ();
RandomTask ();
} else {
RandomTask ();
}
}
}
}
public void FrontMenuShowHide(){
if (isFrontMenuActive == true) {
frontMenu.Play ("FrontMenuOut");
isFrontMenuActive = false;
} else {
frontMenu.Play ("FrontMenu");
isFrontMenuActive = true;
}
}
public void Task1(){
isHintShown = false;
wordCount = (PlayerPrefs.GetInt ("wordCountPrefs"));
taskAllElementsEmpty.SetActive (true);
taskText.text = words[wordCount];
taskInputField.text = "";
taskInputField.ActivateInputField ();
//SoundPlay ();
LoadPicture ();
taskTextEmpty.SetActive (true);
hint.text = "";
taskInputField.placeholder.GetComponent<Text>().text = "Copy the word, please...";
string path = "audio/" + words [wordCount];
taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
taskAudio.Play ();
taskImageEmpty.SetActive (true);
}
public void RandomTask(){
isHintShown = false;
randomWord = Random.Range (0, allWordsCount);
taskAllElementsEmpty.SetActive (true);
taskText.text = words[randomWord];
taskInputField.text = "";
taskInputField.ActivateInputField ();
//SoundPlay ();
LoadRandomPicture ();
taskTextEmpty.SetActive (false);
hint.text = "";
taskImageEmpty.SetActive (true);
taskInputField.placeholder.GetComponent<Text>().text = "What is it?";
string path = "audio/" + words [randomWord];
taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
taskAudio.Play ();
}
public void SoundPlay(){
if (isLearnOn == true) {
string path = "audio/" + words [wordCount];
taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
taskAudio.Play ();
} else {
string path = "audio/" + words [randomWord];
taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
taskAudio.Play ();
}
}
public void LoadPicture(){
string path = "img/" + words [wordCount];
taskImage.sprite = (Sprite)Resources.Load(path, typeof(Sprite));
}
public void LoadRandomPicture(){
string path = "img/" + words [randomWord];
taskImage.sprite = (Sprite)Resources.Load(path, typeof(Sprite));
}
public void NextTask(){
wordCount++;
PlayerPrefs.SetInt ("wordCountPrefs", wordCount);
Task1 ();
}
public void LearnIsOn(){
isLearnOn = true;
}
public void LearnIsOff(){
isLearnOn = false;
}
public void CollectPoints(){
collectPoint++;
PlayerPrefs.SetInt ("points", collectPoint);
pointsBoard.text = collectPoint.ToString ();
}
public void ShowHint(){
if (isLearnOn == true ) {
if (innerTaskCount != 0){
hint.text = words [wordCount];
isHintShown = true;
}
} else {
hint.text = words [randomWord];
isHintShown = true;
}
}
public void HideFinishPanel(){
if (isFinishPanelOn == true) {
finishPanel.Play ("FinishPanelOut");
isFinishPanelOn = false;
} else {
finishPanel.Play ("FinishPanel");
isFinishPanelOn = true;
}
}
public string[] words = {
"apple",
"banana",
"big",
"blue",
"book",
"one",
"two",
"colours",
"green",
"orange",
"pencil",
"yellow",
"four",
"five",
"six",
"small",
};
}
`
This happens because Unity initialize serialized public objects itself. When you define your variable first time in script if you initialized it manually, Unity serialize it with your values. Else Unity serialize it with default values.
For example. When you create the script below first time like;
public class GameManager : MonoBehaviour {
public string[] words = {
"one",
"two",
"three",
"four",
"five",
"six",
};
}
Unity serialize words with this values. After that even if you change initial values from script, next time you run, it actually doesn't change.
For this, there are two options. First; define your variable in script with [System.NonSerialized] attribute.
[System.NonSerialized] public string[] words = {};
Second choice, select the gameobject from hierarchy. On inspector, chose your scripts component and Reset it when you change initial variables.
You need to use list in place of array. List allows you to add or delete any item.
List <string> names = new List<string>();
Void Start()
{
names.Add(“apple”);
}
If you want to be able to do both, adding elements in the editor and by script you should rather use a List<string> words and check if the value already exists in the list before adding it in the script:
[SerializeField]
private List<string> words = new List<string>();
private void Start(){
if(!words.Contains("apple")){
words.Add("apple")
}
if(!words.Contains("banana")){
words.Add("banana")
}
}
Independent from that, if you want to update the List/Array also within the Editor I recomend you use the [ContextMenu] tag:
e.g. for your array:
public string[] words; // you don't set it here but expect it to be set in the editor
[ContextMenu("Import scripted array")]
private void ImportScriptedArray(){
// Note in this case I simply overwrite any setting within the editor
// There are multiple ways to prevent this like before using List or other methods
words = new [] {
"bla",
"bli",
"blub"
};
}
This adds the method ImportScriptedArray to the context menu of this component in the editor. So first you have this unset array:
On your script/component you now can click on the settings icon to open the context menu.
And in the context menu click on your just generated Import Scripted Array to import your array from the script.

game maker - how to navigate a map with 2d array

I have to make a navigable map
the starting point is in the center
there are three worlds + the final stage
pressing up I have to navigate from the base to the first level of the first world and go next level in second and third
pressing down I have do go from the third to the second and from the second to the first level and from the first level of the world to the base
pressing left and right I have to change the world
now:
I already made a lot of menus using different methods, but alway using a 1d array
obj_menu:
create event:
///menu
menu[0] = "new";
menu[1] = "load";
menu[2] = "exit";
space = 55;
mpos = 0;
step event:
///move
if(inputs) {
var move = 0;
move -= max(keyboard_check_pressed(vk_up),0);
move += max(keyboard_check_pressed(vk_down),0);
if(move != 0) {
mpos += move;
if(mpos < 0) {
mpos = array_length_1d(saveload) -1;
}
if(mpos > array_length_1d(saveload) -1) {
mpos = 0;
}
}
//push
if(keyboard_check_pressed(vk_enter)) {
scr_menu();
}
}
scr_menu();
switch(mpos) {
case 0: { scr_new_game(); break; } //new
case 1: { scr_load_game(); break; } //load
case 2: { game_end(); break; } //exit
default: { break; }
}
This time I have to navigate in a 2d array
I did this:
obj_map:
create event:
///navigation setup
if(crash_to_base) { lvl[0,0] = true }
if(base_to_ruins_1) { lvl[1,0] = true }
if(ruins_1_to_ruins_2) { lvl[1,1] = true }
if(ruins_2_to_ruins_3) { lvl[1,2] = true }
if(base_to_city_1) { lvl[2,0] = true }
if(city_1_to_city_2) { lvl[2,1] = true }
if(city_2_to_city_3) { lvl[2,2] = true }
if(base_to_lab_1) { lvl[3,0] = true }
if(lab_1_to_lab_2) { lvl[3,1] = true }
if(lab_2_to_lab_3) { lvl[3,2] = true }
if(base_to_castle) { lvl[4,0] = true }
//posizione del menu
mposh = 0;
mposv = 0;
mpos[mposv,mposh] = 0;
step event:
///map navigation
if(inputs) {
moveh -= max(keyboard_check_pressed(vk_left),0);
moveh += max(keyboard_check_pressed(vk_right),0);
movev -= max(keyboard_check_pressed(vk_up),0);
movev += max(keyboard_check_pressed(vk_down),0);
if(moveh != 0) {
//mposh += move;
}
if(movev != 0) {
//mposv += move;
}
push = keyboard_check_pressed(vk_enter);
if(push) {
scr_map();
}
}
how to translate the first method to de sencond need??
Not quite sure what your having difficulty with, perhaps you could elaborate on what exactly the problem is? On a side note however your 1D menu navigation code can be greatly simplified to:
mpos += keyboard_check_pressed(vk_up) - keyboard_check_pressed(vk_down);
var len = array_length_1d(saveload);
if (mpos < 0) { mpos = len - 1; }
if (mpos > len - 1) { mpos = 0; }
and in terms of a 2d map navigation system, it might not be beneficial to use 2d arrays and instead you could use a ds_map which allows you to store all information on each location in one data structure. For instance
var lvlMap = ds_map_create()
lvlMap[?"base-title"] = "Base"
lvlMap[?"base-travel-right"] = "crash"
lvlMap[?"base-travel-left"] = "fortress"
then when you try to move right/left:
var next_location = lvlMap[?current_location+"-travel-"+direction]
current_location = next_location

UISwipeGestureRecogniser not being recognised

I have a UIScrollView into which I am creating and adding UILabels containing the results of a simple LINQ query.
I have set up a UISwipeGestureRecognizer within the loop that generates the labels (iOS: issues with UIGestureRecognisers vs Subviews says I need a new recogniser for each control - I'm assuming I can do with a UILabel the same as UIImageView for adding a recogniser) and then added the recogniser to the label.
When the view containing the UIScrollView is started, the scrollview works as expected, but the swipe isn't.
Caveat : only tried this on the simulator, my iPhone is acting up.
private void CreateViewHistory()
{
float xtext = 4f;
float y = 4f;
int c = 0;
var tv = tank.Events.OrderByDescending(t => t.Date).ToList();
tbiHistClearAll.Enabled = enableDelete;
//tgrRemove.AddTarget(this, new Selector("screenSwipe"));
//pgrRemove.DelaysTouchesBegan = true;
foreach (var e in tv)
{
var tgrRemove = new UISwipeGestureRecognizer()
{
NumberOfTouchesRequired = 1,
Direction = UISwipeGestureRecognizerDirection.Right,
};
tgrRemove.AddTarget(this, new Selector("screenSwipe"));
svHistoryEvents.PanGestureRecognizer.RequireGestureRecognizerToFail(tgrRemove);
string info = string.Format("{0} - {1}{2} ({3})\n{4} - {5}\n{6} - {7}\n{8} - {9}", e.EventType, e.Volume, AppDelegate.Self.db.getShortVolumeUnits(), e.Date.ToShortDateString(),
StringUtils.GetString("Sowcrop.Implement"), e.Implement != null ? e.Implement.ImplementType : StringUtils.GetString("Common.NonRecorded"),
StringUtils.GetString("Common.User"), StringUtils.GetString("Common.NonRecorded"),
StringUtils.GetString("Common.Notes"), !string.IsNullOrEmpty(e.Notes) ? e.Notes : StringUtils.GetString("Common.NonRecorded"));
var lbl = new UILabel()
{
UserInteractionEnabled = true
};
lbl = UICreation.MakeLabelWithTag(svHistoryEvents, new RectangleF(xtext, y, 320f, 90f), info, UITextAlignment.Left, UIColor.Black, false, 4, c);
lbl.AddGestureRecognizer(tgrRemove);
svHistoryEvents.AddSubview(lbl);
lblTemp.Add(lbl);
c++;
y += 94f;
}
UIUtils.ResizeScrollView(svHistoryEvents);
}
[Export("screenSwipe")]
public void SwipeRemove(UIGestureRecognizer s)
{
var swipe = s as UIGestureRecognizer;
var tv = tank.Events.OrderByDescending(t => t.Date).ToList();
var txt = swipe.View as UILabel;
switch (swipe.State)
{
case UIGestureRecognizerState.Began:
Console.WriteLine("Swipe began");
break;
case UIGestureRecognizerState.Changed:
Console.WriteLine("Swipe changed");
tv.RemoveAt(txt.Tag);
CreateViewHistory();
break;
case UIGestureRecognizerState.Ended:
Console.WriteLine("Swipe ended");
break;
case UIGestureRecognizerState.Cancelled:
Console.WriteLine("Swipe cancelled");
break;
}
}
MakeLabelWithTag generates a UILabel which can then be added to the scrollview.
Am I missing something here, or do I need to do something special as the label is held within a scrollview?
I've also tried what has been suggested at UISwipeGestureRecogniser in a UIScrollView, but still without success.
Found the problem and it's probably the dumbest thing I've encountered in a long time!
To get the swipe gesture to work within a scrollview, you have to first encompass whatever it is you want to add within a UIView and then add that to the scrollview.
To therefore get a swipe within a scrollview to work, you need to do the following
private void CreateViewHistory()
{
foreach (var i in svHistoryEvents.Subviews)
if (i is UIView)
i.RemoveFromSuperview();
float xtext = 4f;
float y = 4f;
int c = 0;
tbiHistClearAll.Enabled = enableDelete;
foreach (var e in tv)
{
var tgrRemove = new UISwipeGestureRecognizer()
{
NumberOfTouchesRequired = 1,
Direction = UISwipeGestureRecognizerDirection.Right,
};
tgrRemove.AddTarget(this, new Selector("screenSwipe"));
var view = new UIView(new RectangleF(xtext, y, 320f, 90f));
svHistoryEvents.PanGestureRecognizer.RequireGestureRecognizerToFail(tgrRemove);
string info = string.Format("{0} - {1}{2} ({3})\n{4} - {5}\n{6} - {7}\n{8} - {9}", e.EventType, e.Volume, AppDelegate.Self.db.getShortVolumeUnits(), e.Date.ToShortDateString(),
StringUtils.GetString("Sowcrop.Implement"), e.Implement != null ? e.Implement.ImplementType : StringUtils.GetString("Common.NonRecorded"),
StringUtils.GetString("Common.User"), StringUtils.GetString("Common.NonRecorded"),
StringUtils.GetString("Common.Notes"), !string.IsNullOrEmpty(e.Notes) ? e.Notes : StringUtils.GetString("Common.NonRecorded"));
var lbl = new UILabel()
{
UserInteractionEnabled = true
};
lbl = UICreation.MakeLabelWithTag(svHistoryEvents, new RectangleF(0, 0, 320f, 90f), info, UITextAlignment.Left, UIColor.Black, false, 4, c);
view.AddGestureRecognizer(tgrRemove);
view.AddSubview(lbl);
svHistoryEvents.AddSubview(view);
lblTemp.Add(lbl);
c++;
y += 94f;
}
UIUtils.ResizeScrollView(svHistoryEvents);
}
[Export("screenSwipe")]
public void SwipeRemove(UIGestureRecognizer s)
{
var swipe = s as UIGestureRecognizer;
var txt = swipe.View.Subviews[0] as UILabel;
switch (swipe.State)
{
case UIGestureRecognizerState.Began:
Console.WriteLine("Swipe began");
break;
case UIGestureRecognizerState.Changed:
Console.WriteLine("Swipe changed");
break;
case UIGestureRecognizerState.Ended:
Console.WriteLine("Swipe ended");
tv.RemoveAt(txt.Tag);
CreateViewHistory();
break;
case UIGestureRecognizerState.Cancelled:
Console.WriteLine("Swipe cancelled");
break;
}
}
It is not possible to add just a UILabel and have the swipe act on that, it has to be on a UIView with the label as a subview to it.

Resources