从自定义可编辑UITableViewCell更新另一个字符串 - 在swift中通过引用传递?

时间:2015-08-13 03:01:50

标签: ios parameter-passing

我从UITableViewCell创建了一个类,允许我编辑正确的详细文本。它使用UITextField作为editableAccessoryView。代码如下。

问题是我需要根据更改更新字符串。即编辑完成后,将使用textField.text字符串更新字符串。

在另一种语言中,我可能在UITableViewCell子类中有一个String指针,我将使用我想要更改的字符串的指针进行更新。但是虽然我可以使用import UIKit class EditableRightDetailTableViewCell: UITableViewCell, UITextFieldDelegate { enum TextFieldType { case Text case Numeric } var type = TextFieldType.Text let textField = UITextField(frame: CGRectMake(150, 7, 200, 30)) override func awakeFromNib() { super.awakeFromNib() // Initialization code textField.borderStyle = UITextBorderStyle.RoundedRect textField.textAlignment = NSTextAlignment.Right textField.clearButtonMode = UITextFieldViewMode.Always textField.delegate = self self.editingAccessoryView = textField } override func setSelected(selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } override func setEditing(editing: Bool, animated: Bool) { if !self.editing && editing == true { self.detailTextLabel?.hidden = true textField.text = self.detailTextLabel?.text } else if self.editing && editing == false { self.detailTextLabel?.hidden = false self.detailTextLabel?.text = textField.text } super.setEditing(editing, animated: animated) } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if type == TextFieldType.Numeric { // We ignore any change that doesn't add characters to the text field. // These changes are things like character deletions and cuts, as well // as moving the insertion point. // // We still return true to allow the change to take place. if count(string) == 0 { return true } // Check to see if the text field's contents still fit the constraints // with the new content added to it. // If the contents still fit the constraints, allow the change // by returning true; otherwise disallow the change by returning false. let prospectiveText = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string) return prospectiveText.isNumeric() && count(prospectiveText) <= 11 } return true } } 传递指向函数的指针,但我无法确定如何存储该指针。

有什么想法吗?

// Quick and dirty - error checks omitted for brevity.

#include <iostream>
#include <string>
#include <conio.h>

#include <WinSock2.h>
#include <ws2tcpip.h>

using namespace std;

void chat (int socket_d)

{
    while (true)
    {
        if (_kbhit ())
        {
            char ch;
            ch = _getche();
            int n;
            n = send (socket_d, &ch, 1, 0);
            if (ch == '\r')
            {
                cout << "\n";
            }
        }

        int n;
        int count = 0;
        char byte; // Read one byte at a time - is this efficient?
        n = recv (socket_d, &byte, 1, 0);
        if (n <= 0)
        {
            if (WSAGetLastError() != WSAEWOULDBLOCK) // A real problem - not just avoiding blocking.
            {
                cout << "Terminated " << WSAGetLastError() << "\n";
                return;
            }
        }
        else
        {
            cout << (char)byte;
            if ((char) byte == '\r')
                cout << "\n";
        }
    }
}

int main (int argc, char * argv [])

{
    // Messy process with windows networking - "start" the networking API.
    WSADATA wsaData;
    int result = WSAStartup (MAKEWORD (2, 2), &wsaData);

    unsigned short port = 25565;

    // If argument is IP address - be a client and connect to it. Otherwise
    // be a server.
    if (argc > 1)
    {
        int socket_d;
        socket_d = socket (AF_INET, SOCK_STREAM, 0);

        // be a client.
        struct sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr (argv[1]); // Parse the string and create the 32 bit address.
        server_addr.sin_port = htons (port); // Watch out for the endian conversion!

        connect (socket_d, (sockaddr *) &server_addr, sizeof (server_addr));

        u_long iMode=1;
        ioctlsocket (socket_d, FIONBIO, &iMode); // put the socket into non-blocking mode.

        chat (socket_d);

        closesocket (socket_d);
    }
    else
    {
        // be a server
        int listen_socket_d;
        int connection_socket_d;

        listen_socket_d = socket (AF_INET, SOCK_STREAM, 0);

        struct sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = INADDR_ANY; // A placeholder that will be replaced with my own address.
        server_addr.sin_port = htons (port); // Watch out for the endian conversion!

        bind (listen_socket_d, (struct sockaddr *) &server_addr, sizeof (server_addr));

        int backlog = 5;
        listen (listen_socket_d, backlog);

        // take only the first connection.
        struct sockaddr_storage their_addr; 
        int their_addr_size = sizeof(their_addr);
        connection_socket_d = accept (listen_socket_d, (struct sockaddr *) &their_addr, &their_addr_size);

        u_long iMode=1;
        ioctlsocket (connection_socket_d, FIONBIO, &iMode); // put the socket into non-blocking mode.

        chat (connection_socket_d);
        closesocket (connection_socket_d);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

不良做法

你真的不想保留UITableViewCell中对象的指针。首先,它们通常由操作系统缓存,并按需加载,简而言之,您不应该尝试拥有它们,并且当然会保留指针。

良好做法

如果您的数据发生变化,请告诉UITableView重绘该单元格。您甚至可以重新绘制一个新的,不同的UITableViewCell。 (您甚至可以使用通知,将视图与模型进一步分离

<强>夫特

self.tableView.beginUpdates()
let indexPath = NSIndexPath(forRow: row, inSection: section)
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
self.tableView.endUpdates()

<强>的OBJ-C

[self.tableView beginUpdates];
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

答案 1 :(得分:0)

如果有人感兴趣,他就是我的实施:

可编辑的UITextViewCell。它应该在IB中设置为Right Detail。当表视图设置为编辑时,将出现UITextField。

import UIKit

class StringFieldDelegate: NSObject, UITextFieldDelegate {

    var value: String

    var valueChanged: Optional<() -> ()> = nil
    func invokeValueChanged() {
        self.valueChanged?()
    }

    init(value: String) {
        self.value = value
    }

    func textFieldDidEndEditing(textField: UITextField) {
        value = textField.text
        invokeValueChanged()
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        value = textField.text
        invokeValueChanged()
        return true
    }
}

这是代表。注意值更改变量。可以为其分配一个闭包,以便在更新值时运行

ViewController

然后在var nameField: StringFieldDelegate! 我们创建像

这样的变量
viewDidLoad

并在cell.textField.delegate = nameField

中初始化它们

在单元格加载部分,我们可以设置单元格的委托

shouldChangeCharactersInRange

现在,当单元格完成编辑或按下返回时,nameField将更新。 (对于即时更新,您必须实施invokeValueChanged并更新值并在其中触发nameField.valueChanged = { println(nameField.value) }

此外,您可以为值更改时分配闭包,例如

shouldChangeCharactersInRange

委托可用于任何UITextField。如果您实施func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if count(string) == 0 { return true } let prospectiveText = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string) return prospectiveText.isNumeric() } ,您可以执行以下操作:

extension String {

    // Returns true if the string represents a proper numeric value.
    // This method uses the device's current locale setting to determine
    // which decimal separator it will accept.
    func isNumeric() -> Bool
    {
        let scanner = NSScanner(string: self)

        // A newly-created scanner has no locale by default.
        // We'll set our scanner's locale to the user's locale
        // so that it recognizes the decimal separator that
        // the user expects (for example, in North America,
        // "." is the decimal separator, while in many parts
        // of Europe, "," is used).
        scanner.locale = NSLocale.currentLocale()

        return scanner.scanDecimal(nil) && scanner.atEnd
    }

}

将使文本字段仅接受使用扩展名

的数字字符
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, env('PAYPAL_HOST_URL'));
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        // curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: $pp_hostname"));
        $res = curl_exec($ch);
        curl_close($ch);

        if(!$res){
            //HTTP ERROR
        } else {
             // parse the data
            $lines = explode("\n", $res);
            $keyarray = array();
            if (strcmp ($lines[0], "SUCCESS") == 0) {

                for ($i=1; $i<count($lines);$i++) {

                    list($key,$val) = explode("=", $lines[$i]);

                    $keyarray[urldecode($key)] = urldecode($val);

                }