Gowhich

Durban's Blog

在ios开发中,电子邮件的发送,看起来是很简单的

只要使用这个MFMailComposeViewControllerDelegate代理就好了

同时还有调用#import <MessageUI/MessageUI.h>这个库

演示一下吧

MailViewController.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// MailViewController.h
// Mail
//
// Created by david on 13-8-2.
// Copyright (c) 2013年 WalkerFree. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface MailViewController : UIViewController<MFMailComposeViewControllerDelegate, UINavigationBarDelegate>
- (IBAction)showMailPicker:(id)sender;

@end

MailViewController.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//
// MailViewController.m
// Mail
//
// Created by david on 13-8-2.
// Copyright (c) 2013年 WalkerFree. All rights reserved.
//

#import "MailViewController.h"

@interface MailViewController ()

@end

@implementation MailViewController

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}



- (IBAction)showMailPicker:(id)sender {
if([MFMailComposeViewController canSendMail]){
[self displayMailComposerSheet];
}else{
NSLog(@"Device not configured to send SMS.");
}

}

- (void)displayMailComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;

[picker setSubject:@"Hello from California!"];

// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:@"xx@xx"];
NSArray *ccRecipients = [NSArray arrayWithObjects:@"xx@xx", @"xx@xx", nil];
NSArray *bccRecipients = [NSArray arrayWithObject:@"xx@xx"];

[picker setToRecipients:toRecipients];
[picker setCcRecipients:ccRecipients];
[picker setBccRecipients:bccRecipients];

// Attach an image to the email
NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"jpg"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:@"rainy"];

// Fill out the email body text
NSString *emailBody = @"It is raining in sunny California!";
[picker setMessageBody:emailBody isHTML:NO];

[self presentViewController:picker animated:YES completion:NULL];
}

#pragma mark - delegate Methods

- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error{
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(@"Result: Mail sending canceled") ;
break;
case MFMailComposeResultSaved:
NSLog(@"Result: Mail saved") ;
break;
case MFMailComposeResultSent:
NSLog(@"Result: Mail sent") ;
break;
case MFMailComposeResultFailed:
NSLog(@"Result: Mail sending failed") ;
break;
default:
NSLog(@"Result: Mail not sent") ;
break;
}

[self dismissViewControllerAnimated:YES completion:NULL];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end

运行一下就可以了。如果提示“Device not configured to send SMS.”

那么请在设置中打开邮件那个选项吧

django模板内的字符串截取

1,变量前30个字符,用于中文不行

1
{{ content |truncatewords:"30"}}

取变量前500个字符,可用于中文

1
{{ content |slice:"30" }} 

开始展示的前提是,看一下表的结构

1
2
3
4
class Person(models.Model):
first_name = models.CharField(...)
last_name = models.CharField(...)
birth_date = models.DateField(...)

1,Performing raw SQL queries

你可以直接执行一个语句像这样

1
2
for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)

官方提示不要使用下面这种方式

1
2
3
lname = 'Doe'
query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
Person.objects.raw(query)

2,Executing custom SQL directly

Sometimes even Manager.raw() isn’t quite enough: you might need to perform queries that don’t map cleanly to models, or directly execute UPDATE, INSERT, or DELETE queries.

是的,有时候Raw Sql Queries是满足不了我们的需求的,那么我们就直接执行一下好了。

1
2
3
4
5
cursor = connection.cursor()
cursor.execute("UPDATE myapp_person SET first_name = 1 WHERE first_name = %s", [self.bar])
cursor.execute("SELECT `last_name` FROM myapp_person WHERE last_name = %s", [self.baz])
row = cursor.fetchone()
print_r(row)

还不错,需求挺大,满足也挺大,操作也简便,对项目的操作很便利

django的admin组件默认显示为英文,使用中还是有很多不方便的。其实,django还是做好了国际化的工作的,要实现语言的转变,只需要如下操作:

在settings.py中找到MIDDLEWARE_CLASSES,在 'django.contrib.sessions.middleware.SessionMiddleware'后面添加一个中间件 'django.middleware.locale.LocaleMiddleware',启动django,就会发现admin显示为中文的了

点击编辑区以外的地方(UIView)

这是一种很直觉的方法,当不再需要使用虚拟键盘时,只要点击虚拟键盘和编辑区域外的地方,就可以将键盘收起,下面程式码是在 UIView 中内建的触碰事件方法函式,您可以参考 Touch Panel / 触碰萤幕 / 压力感应器的基本使用方式一文,找到更多关于触碰事件的方法函式。

1
2
3
4
5
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
if (![myTextView isExclusiveTouch]) {
[myTextView resignFirstResponder];
}
}

如果要使用此方式请务必记得,你操作画面的 Custom Class 一定要是 UIView 才行。
画面的 Custom Class 为 UIView

点击编辑区域以外的地方(UIControl)

收起虚拟键盘的方式与前一种相同,但是如果你的触碰事件里已经且写满了程式码,那么就可以考虑使用,UIControl 的 Touch Up Inside 事件来收起键盘,方法是将以下程式码与 UIControl 的 Touch Up Inside 事件连结即可。

1
2
3
- (IBAction)dismissKeyboard:(id)sender {  
[myTextView resignFirstResponder];
}

如果要使用此方式请务必记得,你操作画面的 Custom Class 一定要是 UIControl 才行。
画面的 Custom Class 为 UIControl
将收起键盘的方法与 UIControl 事件连结

使用制作收起键盘的按钮

当没有编辑区域以外的地方可供点击来收起键盘,自己制作一个按钮来收起目前的虚拟键盘,也是一个不错的方法,由于按钮必须在虚拟键盘出现才能显示于画面上,因此必须借用 NSNotificationCenter 来帮助我们判断目前键盘的状态。
首先在 viewDidLoad: 事件中,向 NSNotificationCenter 进行註册,告诉 NSNotificationCenter 我们的 doneButtonshow: 方法函式。

1
2
3
4
- (void)viewDidLoad {  
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (doneButtonshow:) name: UIKeyboardDidShowNotification object:nil];
}

现在每当虚拟键盘出现时,就会自动呼叫我们自定义的 doneButtonshow: 方法函式,接下来只要在该方法函式里定义按钮出现的方法即可。

1
2
3
4
5
6
7
8
-(void) doneButtonshow: (NSNotification *)notification {  
doneButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
doneButton.frame = CGRectMake(0, 228, 70, 35);
[doneButton setTitle:@"完成编辑" forState: UIControlStateNormal];
[doneButton addTarget: self action:@selector(hideKeyboard) forControlEvents: UIControlEventTouchUpInside];

[self.view addSubview:doneButton];
}

最后是实作按钮按下去时的 hideKeyboard: 方法函式,务必记得要在函式中移除该按钮。

1
2
3
4
-(void) hideKeyboard {  
[doneButton removeFromSuperview];
[myTextView resignFirstResponder];
}

使用判断输入字元

如果要使用输入特定字元(例如 return 换行字元)来收起键盘,必须先在类别内的 @interface 区段採用 协定,您可以参考 Protocol 协定的使用方式一文,获得更多关于协定的资讯。
在采用 协定之后,接着实作出协定内的 textView:shouldChangeTextInRange:replacementText:方法函式,此方法函式会在字元输入时触发,而回传的 BOOL 值则代表该字元是否要作用,下列程式码就是在此方法函式中,使用判断输入字元的方式来收起虚拟键盘(判断字元为 return 换行字元)。

1
2
3
4
5
6
7
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {  
if ([text isEqualToString:@"\n"]) {
[myTextView resignFirstResponder];
return NO;
}
return YES;
}

最后别忘记在 viewDidLoad: 事件中,将 UITextView 的代理物件指向自己,这样程式才能正确找到实作 协定方法函式的类别。

1
2
3
4
- (void)viewDidLoad  {  
[super viewDidLoad];
myTextView.delegate = self;
}

关于键盘遮蔽的问题

如果您在实作上有遭遇到键盘遮蔽编辑区域的问题,可以参考使用 Animation 解决小键盘挡住 UITextField 的问题一文,透过 Core Graphic 的 Animation 功能,在键盘出现时同时移动编辑区域来解决遮蔽的问题。

实现的步骤一个都不能少

1、要在声明文件中实现 UItextFieldDelegate 协议

2、在实现文件中实现 UItextFieldDelegate 协议 中键盘消失的方法即:

1
2
3
4
5
6
7
-(BOOL)textFieldShouldReturn:(UITextField *)textField{

[textField resignFirstResponder];

return YES;

}

3、在viewDidLoad方法中添加代理。例如:

1
2
3
4
5
6
7
8
-(void)viewDidLoad{

[super viewDidLoad];

//设置代理点击换行,键盘消失

textSample.delegate =self;
}

layoutSubviews何时调用的问题,这个方法是当你需要在调整subview的大小的时候需要重写(我这个翻译不严谨,以下是原文:You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.),但有时候经常指望它被调用的时候没被调用,不希望它被调用的时候被调用了,搞的很上火。根据国外社区一个人帖子,做了总结性翻译。

layoutSubviews在以下情况下会被调用:

1、init初始化不会触发layoutSubviews
2、addSubview会触发layoutSubviews
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4、滚动一个UIScrollView会触发layoutSubviews
5、旋转Screen会触发父UIView上的layoutSubviews事件
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

最近在官方中有一份关于,app icons的说明。简单 说了一些不同尺寸的app icons的使用

尺寸的类型有

57:这种型号的尺寸的图片主要用于(Homescreen icon on iPhone/iPod touch),在iPhone/iPod touch的主屏幕上

72:这种型号的尺寸的图片主要用于(Homescreen icon on iPad),在iPad的主屏幕上

114:上面的一倍,这种尺寸的图片用于(Homescreen icon on iPhone Retina),在iPhone Retina的主屏幕上

65:这种型号的图片主要用于(Icon in Spotlight and Settings app on iPhone/iPod touch and icon in Settings app on iPad),说到Spotlight这个,大家都知道的,没错就是搜索时,出现的,如果不知道,说明你安装的应用还不够多,哈哈

50:这个大小的图片,(Icon in Spotlight on iPad),是存在于iPad上的,说的跟上面那个型号差不多,就是小了点,但是这个很重要,尤其是在ios开发中

58:这个尺寸的图片,用过iPhone5的或者有Retina屏都知道(Icon in Spotlight and Settings app on iPhone Retina),没错,就是在那里使用的。

114:这个尺寸的介绍是这样的(Icon in iTunes for Ad Hoc distribution builds),估计是跟开发有关点的,但是事实上在iPunes里面也能看得到的,

基于以上尺寸的图片,在自己项目开发中,显的很重要,不同尺寸出来的效果是不一样,尤其是对已苹果这个追求完美的产品,不容小视

关于自定义UIScrollview的方式,其实很简单,但是如何做到横向滚动,我自己是第一次使用,

先来定义一个类吧:customScrollView.h

1
2
3
4
5
#import <UIKit/UIKit.h>

@interface customScrollView : UIScrollView <UIScrollViewDelegate>

@end

下面看customScrollView.m的定义

1
2
@property (nonatomic, strong) NSMutableArray *visibleLabels;
@property (nonatomic, strong) UIView *labelContainerView;

定义两个属性,第一个是label数组,第二个是一个UIView

然后实现一下初始化的代码操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
self.contentSize = CGSizeMake(5000, self.frame.size.height);

_visibleLabels = [[NSMutableArray alloc] init];

_labelContainerView = [[UIView alloc] init];
self.labelContainerView.frame = CGRectMake(0, 0, self.contentSize.width, self.contentSize.height/2);
[self addSubview:self.labelContainerView];

[self.labelContainerView setUserInteractionEnabled:NO];

// hide horizontal scroll indicator so our recentering trick is not revealed
[self setShowsHorizontalScrollIndicator:NO];
}
return self;
}

都是一些基本的初始化的操作

下面看一下这个方法,这个方法,是在UIScrollView在滚动的时候进行调用的

1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)layoutSubviews
{
[super layoutSubviews];

[self recenterIfNecessary];

// tile content in visible bounds
CGRect visibleBounds = [self convertRect:[self bounds] toView:self.labelContainerView];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
CGFloat maximumVisibleX = CGRectGetMaxX(visibleBounds);

[self tileLabelsFromMinX:minimumVisibleX toMaxX:maximumVisibleX];
}

里面有一个方法,我写下下面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)recenterIfNecessary
{
CGPoint currentOffset = [self contentOffset];
CGFloat contentWidth = [self contentSize].width;
CGFloat centerOffsetX = (contentWidth - [self bounds].size.width) / 2.0;
CGFloat distanceFromCenter = fabs(currentOffset.x - centerOffsetX);

if (distanceFromCenter > (contentWidth / 4.0))
{
self.contentOffset = CGPointMake(centerOffsetX, currentOffset.y);

// move content by the same amount so it appears to stay still
for (UILabel *label in self.visibleLabels) {
CGPoint center = [self.labelContainerView convertPoint:label.center toView:self];
center.x += (centerOffsetX - currentOffset.x);
label.center = [self convertPoint:center toView:self.labelContainerView];
}
}
}

这个方法是用来控制label的位置的。

当UIScrollview在滚动的时候,我们需要做一些操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
- (UILabel *)insertLabel
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 500, 80)];
[label setNumberOfLines:3];
[label setText:@"1024 Block Street\nShaffer, CA\n95014"];
[self.labelContainerView addSubview:label];

return label;
}


- (CGFloat)placeNewLabelOnRight:(CGFloat)rightEdge
{
UILabel *label = [self insertLabel];
[self.visibleLabels addObject:label]; // add rightmost label at the end of the array

CGRect frame = [label frame];
frame.origin.x = rightEdge;
frame.origin.y = [self.labelContainerView bounds].size.height - frame.size.height;
[label setFrame:frame];

return CGRectGetMaxX(frame);
}

- (CGFloat)placeNewLabelOnLeft:(CGFloat)leftEdge
{
UILabel *label = [self insertLabel];
[self.visibleLabels insertObject:label atIndex:0]; // add leftmost label at the beginning of the array

CGRect frame = [label frame];
frame.origin.x = leftEdge - frame.size.width;
frame.origin.y = [self.labelContainerView bounds].size.height - frame.size.height;
[label setFrame:frame];

return CGRectGetMinX(frame);
}

- (void)tileLabelsFromMinX:(CGFloat)minimumVisibleX toMaxX:(CGFloat)maximumVisibleX
{
// the upcoming tiling logic depends on there already being at least one label in the visibleLabels array, so
// to kick off the tiling we need to make sure there's at least one label
if ([self.visibleLabels count] == 0)
{
[self placeNewLabelOnRight:minimumVisibleX];
}

// add labels that are missing on right side
UILabel *lastLabel = [self.visibleLabels lastObject];
CGFloat rightEdge = CGRectGetMaxX([lastLabel frame]);
while (rightEdge < maximumVisibleX)
{
rightEdge = [self placeNewLabelOnRight:rightEdge];
}

// add labels that are missing on left side
UILabel *firstLabel = self.visibleLabels[0];
CGFloat leftEdge = CGRectGetMinX([firstLabel frame]);
while (leftEdge > minimumVisibleX)
{
leftEdge = [self placeNewLabelOnLeft:leftEdge];
}

// remove labels that have fallen off right edge
lastLabel = [self.visibleLabels lastObject];
while ([lastLabel frame].origin.x > maximumVisibleX)
{
[lastLabel removeFromSuperview];
[self.visibleLabels removeLastObject];
lastLabel = [self.visibleLabels lastObject];
}

// remove labels that have fallen off left edge
firstLabel = self.visibleLabels[0];
while (CGRectGetMaxX([firstLabel frame]) < minimumVisibleX)
{
[firstLabel removeFromSuperview];
[self.visibleLabels removeObjectAtIndex:0];
firstLabel = self.visibleLabels[0];
}
}

一个是插入label的方法

一个是从左侧到右侧滑动的操作

一个是从右侧到左侧滑动的操作

还有一个方法是用来控制label的

好了。一些基本的操作就在这里面了,打击可以自己复制一份自己看看

我来个完整版的,当然我这个调用的时候,是在自己的xib文件中调用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#import "customScrollView.h"

@interface InfiniteScrollView ()

@property (nonatomic, strong) NSMutableArray *visibleLabels;
@property (nonatomic, strong) UIView *labelContainerView;

@end


@implementation InfiniteScrollView

- (id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
self.contentSize = CGSizeMake(5000, self.frame.size.height);

_visibleLabels = [[NSMutableArray alloc] init];

_labelContainerView = [[UIView alloc] init];
self.labelContainerView.frame = CGRectMake(0, 0, self.contentSize.width, self.contentSize.height/2);
[self addSubview:self.labelContainerView];

[self.labelContainerView setUserInteractionEnabled:NO];

// hide horizontal scroll indicator so our recentering trick is not revealed
[self setShowsHorizontalScrollIndicator:NO];
}
return self;
}


#pragma mark - Layout

// recenter content periodically to achieve impression of infinite scrolling
- (void)recenterIfNecessary
{
CGPoint currentOffset = [self contentOffset];
CGFloat contentWidth = [self contentSize].width;
CGFloat centerOffsetX = (contentWidth - [self bounds].size.width) / 2.0;
CGFloat distanceFromCenter = fabs(currentOffset.x - centerOffsetX);

if (distanceFromCenter > (contentWidth / 4.0))
{
self.contentOffset = CGPointMake(centerOffsetX, currentOffset.y);

// move content by the same amount so it appears to stay still
for (UILabel *label in self.visibleLabels) {
CGPoint center = [self.labelContainerView convertPoint:label.center toView:self];
center.x += (centerOffsetX - currentOffset.x);
label.center = [self convertPoint:center toView:self.labelContainerView];
}
}
}

- (void)layoutSubviews
{
[super layoutSubviews];

[self recenterIfNecessary];

// tile content in visible bounds
CGRect visibleBounds = [self convertRect:[self bounds] toView:self.labelContainerView];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
CGFloat maximumVisibleX = CGRectGetMaxX(visibleBounds);

[self tileLabelsFromMinX:minimumVisibleX toMaxX:maximumVisibleX];
}


#pragma mark - Label Tiling

- (UILabel *)insertLabel
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 500, 80)];
[label setNumberOfLines:3];
[label setText:@"1024 Block Street\nShaffer, CA\n95014"];
[self.labelContainerView addSubview:label];

return label;
}


- (CGFloat)placeNewLabelOnRight:(CGFloat)rightEdge
{
UILabel *label = [self insertLabel];
[self.visibleLabels addObject:label]; // add rightmost label at the end of the array

CGRect frame = [label frame];
frame.origin.x = rightEdge;
frame.origin.y = [self.labelContainerView bounds].size.height - frame.size.height;
[label setFrame:frame];

return CGRectGetMaxX(frame);
}

- (CGFloat)placeNewLabelOnLeft:(CGFloat)leftEdge
{
UILabel *label = [self insertLabel];
[self.visibleLabels insertObject:label atIndex:0]; // add leftmost label at the beginning of the array

CGRect frame = [label frame];
frame.origin.x = leftEdge - frame.size.width;
frame.origin.y = [self.labelContainerView bounds].size.height - frame.size.height;
[label setFrame:frame];

return CGRectGetMinX(frame);
}

- (void)tileLabelsFromMinX:(CGFloat)minimumVisibleX toMaxX:(CGFloat)maximumVisibleX
{
// the upcoming tiling logic depends on there already being at least one label in the visibleLabels array, so
// to kick off the tiling we need to make sure there's at least one label
if ([self.visibleLabels count] == 0)
{
[self placeNewLabelOnRight:minimumVisibleX];
}

// add labels that are missing on right side
UILabel *lastLabel = [self.visibleLabels lastObject];
CGFloat rightEdge = CGRectGetMaxX([lastLabel frame]);
while (rightEdge < maximumVisibleX)
{
rightEdge = [self placeNewLabelOnRight:rightEdge];
}

// add labels that are missing on left side
UILabel *firstLabel = self.visibleLabels[0];
CGFloat leftEdge = CGRectGetMinX([firstLabel frame]);
while (leftEdge > minimumVisibleX)
{
leftEdge = [self placeNewLabelOnLeft:leftEdge];
}

// remove labels that have fallen off right edge
lastLabel = [self.visibleLabels lastObject];
while ([lastLabel frame].origin.x > maximumVisibleX)
{
[lastLabel removeFromSuperview];
[self.visibleLabels removeLastObject];
lastLabel = [self.visibleLabels lastObject];
}

// remove labels that have fallen off left edge
firstLabel = self.visibleLabels[0];
while (CGRectGetMaxX([firstLabel frame]) < minimumVisibleX)
{
[firstLabel removeFromSuperview];
[self.visibleLabels removeObjectAtIndex:0];
firstLabel = self.visibleLabels[0];
}
}

@end

  1. 基本操作:启用防火墙
    这里的指令都是从 Linux 控制终端(命令行)直接输入的。
    输入下面的两条指令来启用防火墙:
1
2
chkconfig iptables on
service iptables start

其中上一条是将 iptables 加入到系统服务,随系统启动而启动;下一条是直接启动 iptables 服务。
重起防火墙:

1
service iptables restart

停止防火墙:

1
service iptables stop

2,配置 /etc/sysconfig/iptables 文件
虽然可以通过 iptables 指令来编辑防火墙规则,可是对于大量的规则来说一条一条的输入总是很麻烦,实际上可以直接按照正确格式编辑 iptables 的配置文件,然后重新加载 iptables 即可使之生效。
要编辑 /etc/sysconfig/iptables,输入:

1
# vi /etc/sysconfig/iptables

可以看到文件中存储的前述默认规则显示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 1.2.3.4 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

其中 -j 参数表示 jump 跳转到。

可以看到其中的规则形式与我们通过命令行来输入的规则是一样的,因为启用 iptables 的时候就是将此文件中的指令一行一行的自动加载的,就像批处理一样。

0%