Search code examples
iosrubymotion

TextField not showing on a view that has table on top and textfield at bottom


I have a view with a table on top and textfield at the bottom. Kind of like chat. I envision that when the user types something in the TextField and presses send button (not shown in screenshot) the table will update with that entry.

enter image description here

Question

My problem is that when I click into the TextField, the keyboard shows up but the TextField isn't visible. As shown in the screen shot below.

enter image description here

This is how I'm making the two views:

@my_table = rmq(self.view).append(UITableView, :top_style).get
@bottom = rmq(self.view).append(UIView, :bottom_style).get
@bottom = rmq(:bottom_style)
@send = @bottom.append(UITextField, :send).get

Stylesheet

  def top_style(st)
    st.frame = {t: 0, l: 0, w: screen_width, h: screen_height - 100}
    st.background_color = color.white
  end

  def bottom_style(st)
    st.frame = {t: screen_height-100, l: 0, w: screen_width, h: screen_height}
    st.background_color = color.battleship_gray
  end

  def send(st)
    st.frame = {l: 3, t: 5, w: 220, h: 30}
    st.background_color = color.white
    st.view.font = font.small
    st.layer.cornerRadius = 5
    st.view.placeholder = "say something..."
  end

update

output from RMQ log

─── UIView  282653120  {l: 0, t: 64, w: 320, h: 504}
    ├─── UITableView  ( top_style )  264785408  {l: 0, t: 0, w: 320, h: 468}
    │    ├─── UITableViewWrapperView  282624240  {l: 0, t: 0, w: 320, h: 468}
    │    │    ├─── NotesCell  ( note_cell )  282682640  {l: 0, t: 60, w: 320, h: 30}
    │    │    │    ├─── UITableViewCellScrollV  282585904  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    ├─── UITableViewCellContent  282688128  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    │    ├─── UILabel  ( cell_label )  282583168  {l: 15, t: 0, w: 290, h: 30}
    │    │    ├─── NotesCell  ( note_cell )  282696944  {l: 0, t: 30, w: 320, h: 30}
    │    │    │    ├─── UITableViewCellScrollV  282690432  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    ├─── UITableViewCellContent  282617184  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    │    ├─── UILabel  ( cell_label )  282578944  {l: 15, t: 0, w: 290, h: 30}
    │    │    ├─── NotesCell  ( note_cell )  282671168  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    ├─── UITableViewCellScrollV  282723568  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    ├─── UITableViewCellContent  282709936  {l: 0, t: 0, w: 320, h: 30}
    │    │    │    │    │    ├─── UILabel  ( cell_label )  282653440  {l: 15, t: 0, w: 290, h: 30}
    │    ├─── UIImageView  282715328  {l: 316.5, t: 461, w: 3.5, h: 7}
    │    ├─── UIImageView  282714752  {l: 313, t: 464.5, w: 7, h: 3.5}
    ├─── UIView  ( bottom_style )  282440352  {l: 0, t: 468, w: 320, h: 568}
    │    ├─── UITextField  ( send )  282618928  {l: 3, t: 5, w: 220, h: 30}
    │    │    ├─── UITextFieldLabel  282587568  {l: 0, t: 0, w: 220, h: 29}

Solution

  • Where are you creating the views? Inside a custom UITableViewCell? If so, in your layoutSubviews method, make sure not to call super and the system titleview and subtlte view won't be created.

    See here for an example: https://github.com/MohawkApps/aloft/blob/master/app/views/wind_cell.rb#L18

    EDIT... didn't quite understand the question previously.

    Looks like you're going to have to manually reposition the bottom view when the keyboard is shown and hidden. Try something like this:

    def create_stuff
      @my_table = rmq(self.view).append(UITableView, :top_style).get
      @bottom = rmq(self.view).append(UIView, :bottom_style).get
      @bottom = rmq(:bottom_style)
      @send = @bottom.append(UITextField, :send).get
      @send.get.delegate = self # This is crucial for the rest to work
    end
    
    def textFieldDidBeginEditing(textField)
      rmq(@bottom).animate(
        duration: 0.3,
        animations: lambda{|q|
          q.move top: keyboard_height # Animate it somewhere
        }
      )
    end
    
    def textFieldDidEndEditing(textField)
      rmq(@bottom).animate(
        duration: 0.3,
        animations: lambda{|q|
          q.move top: -keyboard_height # Animate it somewhere
        }
      )
    end
    

    Something along those lines should work.