This blog post is about the Weibo comment list page and how to post comments to Weibo.
As you can see from the above results view, the first cell in the Weibo comment view displays the content of Weibo, And the next cell displays the comment content. The comment content displays the nickname of the reviewer, the comment content and time; the comment view is a simple textview and a comment button, which is simple.
(1) Weibo comment View
(1) Get Weibo comments of the API is the https://api.weibo.com/2/comments/show.json of its request parameters in addition to access_token and Weibo idnumber, I also used a parameter, that is, page, has said before, data is returned on pages. The number of comments returned on one page is 50 by default. You can also set this parameter count to change the number of comments returned on each page, I did not.
So there are three parameters in total.
+ (NSString *)returnCommentUrlStringWithID:(long long)weiboID page:(int)page { NSString *urlString = [[NSString alloc] initWithFormat:@"%@?access_token=%@&id=%lld&page=%d",COMMENTS,[InfoForSina returnAccessTokenString],weiboID,page]; return urlString;}
Comments indicates this API.
Data Request and resolution are as follows:
-(Void) continueloaddata :( INT) page {// GCD asynchronously obtains data dispatch_async (bytes (0, 0), ^ {dispatch_sync (dispatch_get_global_queue (0, 0), ^ {Hud. labeltext = @ "loading comment data... "; [HUD show: Yes]; [self. view addsubview: HUD]; nsstring * urlstring = [infoforsina returncommenturlstringwithid: _ status. statusid page: Page]; nsurl * url = [nsurl urlwithstring: urlstring]; nsurlrequest * request = [[nsurlrequest alloc] initwithurl: URL cachepolicy: nsurlrequestuseprotocolcachepolicy timeoutinterval: 10]; nsdata * commentlistdata = [nsurlconnection sendsynchronousrequest: Request returningresponse: Nil error: Nil]; nsstring * dataliststring = [[nsstring alloc] initwithdata: commentlistdata encoding: enabled]; nsdictionary * datalistdictionary = [dataliststring objectfromjsonstring]; _ totalnum = [[datalistdictionary objectforkey: @ "total_number"] integervalue]; [_ commentarray attributes: [datalistdictionary objectforkey: @ "Comments"];}); dispatch_sync (dispatch_get_main_queue (), ^ {[self. tableview reloaddata]; [HUD removefromsuperview] ;});}
Of course, if there are more than 50 comments on one page, we should continue to load the comments when we continue tableview. Therefore, we need to check whether to continue loading. If the comment is always no more than 50 and
_ Page> (_ totalnum/50 + 1), you do not need to continue the data request. A prompt box is displayed, indicating that all the data has been loaded.
// Process the sliding of tableview to the end-(void) scrollviewdidscroll :( uiscrollview *) scrollview {cgpoint contentoffsetpoint = self. tableview. contentoffset; cgrect frame = self. tableview. frame; If (contentoffsetpoint. y = self. tableview. contentsize. height-frame. size. height) {If (_ totalnum <= 50 | _ I> (_ totalnum/50 + 1) {mbprogresshud * endhud = [[mbprogresshud alloc] init]; endhud. mode = mbprogresshudmodetext; endhud. labeltext = @ "prompt"; endhud. detailslabeltext = @ "scroll to the end"; [self. tableview addsubview: endhud]; [endhud show: Yes]; [endhud hide: Yes afterdelay: 1];} else if (_ totalnum> [_ commentarray count]) {[self continueloaddata: ++ _ I] ;}}
② Display tableview content
First, the first cell is to display Weibo content. Then, we can use segue to transfer the corresponding Weibo content data from the Weibo content view to this comment view, and then display it in this view, the displayed rules are the same as those on the Weibo homepage.
Comment content display we should note that the high cell computing and cell reuse mechanisms may cause overlapping content, which is not difficult, in the previous blog, I have introduced how to solve the problem:
IOS uitableviewcell reuse and iOS tableviewcell dynamically adjust the height.
The following code is directly used:
-(Uitableviewcell *) tableview :( uitableview *) tableview cellforrowatindexpath :( nsindexpath *) indexpath {// configure the cell... if (indexpath. row = 0) {weibocell * cell = [[weibocell alloc] init]; [Cell setupcell: _ Status]; // display Weibo content return cell ;} else {static nsstring * cellidentifier = @ "detailcell"; uitableviewcell * cell = [tableview dequeuereusablecellwithidentifier: cellidentifier forindexpath: Indexpath]; If (cell = nil) {Cell = [[uitableviewcell alloc] initwithstyle: uitableviewcellstyledefault reuseidentifier: cellidentifier];} If (cell! = Nil) {[Cell removefromsuperview];} // comment data nsdictionary * dictionary = [_ commentarray objectatindex: indexpath. row-1]; // get a comment nsstring * timestring = [dictionary objectforkey: @ "created_at"]; // comment time nsstring * commentstring = [dictionary objectforkey: @ "text"]; // The comment content nsdictionary * user = [dictionary objectforkey: @ "user"]; // The comment user nsstring * username = [user objectforkey: @ "screen_name"]; // user name // the user name uilabel * usernamelabel = [[uilabel alloc] initwithframe: cgrectzero]; [usernamelabel setfont: [uifont boldsystemfontofsize: 172.16f]; [usernamelabel settext: username]; usernamelabel. adjustsfontsizetofitwidth = yes; [usernamelabel setframe: cgrectmake (cell_content_margin, cell_content_margin, 160,30)]; usernamelabel. tag = 100; [[Cell viewwithtag: 100] removefromsuperview]; [Cell contentview] addsubview: usernamelabel]; // set the comment release time uilabel * timelabel = [[uilabel alloc] Reverse: cgrectzero]; [timelabel setfont: [uifont systemfontofsize: font_size]; [timelabel settext: [self gettimestring: timestring]; [timelabel settextalignment: nstextalignmentright]; timelabel. adjustsfontsizetofitwidth = yes; [timelabel setframe: cgrectmake (170, cell_content_margin,)]; timelabel. tag = 101; [[Cell viewwithtag: 101] removefromsuperview]; [Cell contentview] addsubview: timelabel]; // comment content uilabel * commentlabel = [[uilabel alloc] initwithframe: cgrectzero]; [commentlabel setlinebreakmode: nslinebreakbywordwrapping]; [commentlabel setnumberoflines: 0]; [commentlabel setfont: [uifont systemfontofsize: font_size]; cgsize constraint = cgsizemake (batch-(batch * 2), maxfloat); cgsize size = [commentstring sizewithfont: [uifont systemfontofsize: font_size] batch: constraint linebreakmode: Batch]; [commentlabel settext: commentstring]; [commentlabel setframe: cgrectmake (cell_content_margin, 30 + 2 * cell_content_margin, cell_content_width-(cell_content_margin * 2), size. height)]; commentlabel. tag = 102; [[Cell viewwithtag: 102] removefromsuperview]; [Cell contentview] addsubview: commentlabel]; return cell ;}}
Note:
1. numberofrowsinsection of tableview cell: 1 + comments should be returned. This 1 indicates the microblog.
2. Because the first cell displays the content of Weibo, the subscript of each comment in the cell indexpath. Row and comment array will be 1 different. That is to say, when indexpath. Row is 2, the subscript of the comment in the comment array is 2-1 = 1. This should be especially careful, otherwise there will be a bug of the array underlying.
This is the cell computing height code.
-(Cgfloat) tableview :( uitableview *) tableview heightforrowatindexpath :( nsindexpath *) indexpath {If (indexpath. row = 0) {// return the height of the cell in the microblog content. The height of the Weibo content is the same as that of the tableview cell on the Weibo homepage. Here, we will not post code to save space. } Else {nsdictionary * dictionary = [_ commentarray objectatindex: indexpath. row-1]; // get a comment. The subscript of an array such as the home page must be-1 nsstring * commentstring = [dictionary objectforkey: @ "text"]; // comment cgsize constraint = cgsizemake (response-(response * 2), maxfloat); cgsize size = [commentstring sizewithfont: [uifont systemfontofsize: font_size] response: constraint linebreakmode: nslinebreakbywordwrapping]; return 30 + 3 * cell_content_margin + size. height ;}}
(2) handling of comments
We set a comment button on the right of the navigation bar. The advantage of using the segue method to connect to the comment view is that the Weibo ID can be passed.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"commentSegue"]) { CommentCreatViewController *vc = [segue destinationViewController]; vc.weiboID = _status.statusId; }}
The API used for sending comments is https://api.weibo.com/2/comments/create.json's response packet access_token,comment (the comment content must be urlencode, and the word count must be between 0 and 140) and the Weibo ID. The HTTP request is post.
Here we can use the third-party class library asihttprequest for processing, or use the built-in method of the system to process asynchronous post.
The following code is provided:
-(Ibaction) commentbutton :( ID) sender {[_ commenttextview resignfirstresponder]; nsstring * content = [[nsstring alloc] initwithstring: _ commenttextview. text]; // calculate the number of words in the content sent to Weibo, and process nsinteger contentlength = content accordingly. length; If (contentlength> 140) {mbprogresshud * overlengthhud = [[mbprogresshud alloc] initwithview: Self. view]; [self. view addsubview: overlengthhud]; overlengthhud. mode = mbprogresshudmo Detext; overlengthhud. labeltext = @ "@"; overlengthhud. detailslabeltext = [nsstring stringwithformat: @ ": % d exceeds the upper limit of 140! ", Contentlength]; [overlengthhud show: Yes]; [overlengthhud hide: Yes afterdelay: 2];} else if (contentlength = 0) {uialertview * Alert = [[uialertview alloc] initwithtitle: @ "prompt" message: @ "Enter the comment! "Delegate: Nil cancelbuttontitle: @" "otherbuttontitles: nil, nil]; [alert show];} else {_ HUD = [[mbprogresshud alloc] init]; _ Hud. dimbackground = yes; _ Hud. labeltext = @ "sending... "; [_ HUD show: Yes]; [self. view addsubview: _ HUD]; nsstring * accesstokenstring = [[nsuserdefaults standarduserdefaults] objectforkey: @ "access_token"]; nsstring * paramstring = [nsstring stringwithformat: @ "comment =%@ & id = % LLD & Ccess_token = % @ ", content, _ weiboid, accesstokenstring]; nsmutabledata * postcommentdata = [[nsmutabledata alloc] init]; [postcommentdata appenddata: [paramstring failed: Failed]; nsmutableurlrequest * request = [nsmutableurlrequest requestwithurl: [nsurl urlwithstring: commentcreat] cachepolicy: Invalid timeoutinterval: 5.0]; [Request sethttpmethod: @ "Post "]; [Request sethttpbody: postcommentdata]; self. connection = [[nsurlconnection alloc] initwithrequest: Request delegate: Self startimmediately: Yes] ;}# Pragma mark-nsurlconnection delegate methods-(void) connection :( nsurlconnection *) connection didreceiveresponse :( nsurlresponse *) response {self. responsedata = [[nsmutabledata alloc] initwithlength: 0];}-(void) connection :( nsurlconnection *) Connection Didreceivedata :( nsdata *) Data {[self. responsedata appenddata: Data];}-(void) response :( nsurlconnection *) THECONNECTION {[_ HUD removefromsuperview]; nserror * error; nsdictionary * dict = [nsjsonserialization jsonobjectwithdata: Self. responsedata options: kniloptions error: & error]; nsstring * textstring = [dict objectforkey: @ "text"]; If (textstring) {mbprogresshud * successhud = [[mbprogr Esshud alloc] init]; successhud. mode = mbprogresshudmodetext; successhud. labeltext = @ "prompt"; successhud. detailslabeltext = @ "the comment is successful! "; [Successhud show: Yes]; [self. view addsubview: successhud]; [successhud hide: Yes afterdelay: 1.3];} else {mbprogresshud * successhud = [[mbprogresshud alloc] init]; successhud. mode = mbprogresshudmodetext; successhud. labeltext = @ "prompt"; successhud. detailslabeltext = @ "An error occurred while posting comments! "; [Successhud show: Yes]; [self. view addsubview: successhud]; [successhud hide: Yes afterdelay: 1.3];} [self. connection cancel];}-(void) connection :( nsurlconnection *) THECONNECTION didfailwitherror :( nserror *) error {mbprogresshud * successhud = [[mbprogresshud alloc] init]; successhud. mode = mbprogresshudmodetext; successhud. labeltext = @ "prompt"; successhud. detailslabeltext = @ "An error occurred while posting comments! "; [Successhud show: Yes]; [self. View addsubview: successhud]; [successhud hide: Yes afterdelay: 1.3]; [self. Connection cancel];}
The code is simple and does not need to be explained.
Now, this part of introduction is over!