iOSTable/iOSTable.DataSource not refreshing as expected from changes in iOSLibTextField

  1. 5 months ago

    I have an application that uses a standard iOSTable connected to a DataSource that implements the recommended methods.

    The RowData() methods returns an iOSCustomTableCell for each row that has two iOSLabels and, depending on the data, either an iOSSwitch, or a subclass of an iOSLibTextField (and I have for testing added an iOSTextField).

    Changing the switch, completing editing of the iOSLibTextField (and in testing the TextChange event of the IOSTextField) all call the same method, which updates the table source data and then calls iOSTable. ReloadData.

    I find that if I change the switch or the iOSTextField, then iOSTable.ReloadData triggers my RowData() methods and the table reloads as expected.

    However, if I change the iOSLibTextField, I can step through and see the same code execute through the iOSTable.ReloadData, but this then is not followed by the iOSTable calling the RowData() method.

    Any Ideas on what I have done wrong on this?

    Using the regular iOSTextField and one declare should be enough to fake the DoneEditing event.

    1. Add a isFocused as Boolean property to your custom cell

    2. Add the following methods to your custom cell

    Public Sub CheckFirstResponder()
      
      declare function isFirstResponder lib "Foundation.Framework" selector "isFirstResponder" (obj_id as Ptr) as boolean
    
    
      if isFirstResponder (iOSTextField1.handle) then
        isFocused = True
      Else
        isFocused = False
      end if
      
      if isFocused = False then
        
       //Call your method here to update the table data
    //Done Editing 
    Edit code here
    
    
      Else
        xojo.core.timer.CallLater(100, AddressOf CheckFirstResponder) 
      end if
      
      
    End Sub
    Public Sub startTimer()
      
      xojo.core.timer.CancelCall(AddressOf CheckFirstResponder)
      xojo.core.timer.CallLater(100, AddressOf CheckFirstResponder)
      
      
      
    End Sub

    3. And in the iOSTextField TextChange event

    isFocused = true
    startTimer()
  2. Greg O

    Jul 1 Xojo Inc scout.galaxy.barn

    Are you calling the ReloadRow method to reload just that row?

  3. No. I am using the the ReloadData (the whole table) method.

    The table is a list of input parameters and the resulting outputs (conceptually a multi variable calculator - Enter any 3 of 4 parameters and the fourth will be calculated) .

    I had originally designed it with a 'Calculate' button so that I wouldn't generate garbage calculations on each keystroke (due to iOSTextField not having a LostFocus or DoneEditing event).

    I replaced the relevant iOSTextField with and iOSLibTextField which does have a rich support of events such as ShouldEndEditing to allow validation. However, this seems to result in some interaction where the table doesn't reload its data on a .ReloadData call, but will if I have toggled a switch or entered data into an ordinary text field.

  4. Jeremie L

    Jul 2 Pre-Release Testers, Xojo Pro, XDC Speakers Answer Europe (France) - getpackr.io
    Edited 5 months ago

    Using the regular iOSTextField and one declare should be enough to fake the DoneEditing event.

    1. Add a isFocused as Boolean property to your custom cell

    2. Add the following methods to your custom cell

    Public Sub CheckFirstResponder()
      
      declare function isFirstResponder lib "Foundation.Framework" selector "isFirstResponder" (obj_id as Ptr) as boolean
    
    
      if isFirstResponder (iOSTextField1.handle) then
        isFocused = True
      Else
        isFocused = False
      end if
      
      if isFocused = False then
        
       //Call your method here to update the table data
    //Done Editing 
    Edit code here
    
    
      Else
        xojo.core.timer.CallLater(100, AddressOf CheckFirstResponder) 
      end if
      
      
    End Sub
    Public Sub startTimer()
      
      xojo.core.timer.CancelCall(AddressOf CheckFirstResponder)
      xojo.core.timer.CallLater(100, AddressOf CheckFirstResponder)
      
      
      
    End Sub

    3. And in the iOSTextField TextChange event

    isFocused = true
    startTimer()
  5. Thank you for the tip. I seem to have implemented it wrong. When I click into the my subclass of IOSTextField (subclassed to support some application specific unit of measure conversions and validations), the simulated application crashes out on a black screen (the simulator itself doesn't crash).

    I have set breakpoints and find that the text change event correctly cals start timer code and this sets up the reference to CheckFirstResponder, calls it and then gets to just prior to the if isFirstResponder... statement, and then crashes on the next step.

    I assume that I have made an error either in the declare or in the passing of the pointer. Quantity is the name of my subclassed iOSTextField and the code I am using is below.

    declare Function isFirstResponder lib "Foundation.Framework" selector "isFirstResonder" (obj_id as Ptr) as Boolean
    
    if isFirstResponder (Quantity.Handle) then
      IsFocused = true
    else
      IsFocused=false
    end if
  6. Jason K

    Jul 6 Pre-Release Testers

    Try changing the lib to “UIKit.framework”

  7. Jeremie L

    Jul 6 Pre-Release Testers, Xojo Pro, XDC Speakers Europe (France) - getpackr.io
    Edited 5 months ago

    You have a typo in your declare, missing a P in responder

  8. Thank you for that, a blinding glimpse of the obvious !!

    All works fine now and I think I am starting to get the hang of declares as I got another one to work from the Apple documentation !

or Sign Up to reply!